Interfaz de usuario para un emulador del microcontrolador 8051 Titulació: Enginyeria Tècnica Industrial en Electrònica Industrial AUTOR:Eduard Sardà Vallduví DIRECTOR: Esteban Del Castillo Pérez FECHA: Julio / 2005 ITF51 INDICE: 1 Memoria descriptiva ...................................................................................5 1.1 Objeto del Proyecto.................................................................................................... 5 1.2 Titular ......................................................................................................................... 5 1.3 Antecedentes ............................................................................................................... 5 1.4 Posibles Soluciones y Solución Adoptada ................................................................ 6 1.5 Descripción general.................................................................................................... 6 1.5.1 Hardware................................................................................................................... 6 1.5.1.1 Generalidades .......................................................................................................... 6 1.5.1.2 Targeta de Comunicaciones .................................................................................... 6 1.5.1.3 Tarjeta Emuladora ................................................................................................... 7 1.5.2 Software..................................................................................................................... 9 1.5.2.1 Generalidades .......................................................................................................... 9 1.5.2.2 Targeta de Comunicaciones .................................................................................... 9 1.5.2.3 El Programa Monitor............................................................................................. 10 1.5.2.4 Interfaz con el Usuario .......................................................................................... 13 2 Presupuesto ................................................................................................40 3 Conclusiones...............................................................................................41 4 Pliego de Condiciones................................................................................42 4.1 Generalidades ........................................................................................................... 42 4.1.1 Condiciones Generales ........................................................................................... 42 4.1.2 Reglamentos y Normas. .......................................................................................... 42 4.1.3 Ejecución del Programa ......................................................................................... 42 4.1.3.1 Comienzo: ............................................................................................................. 42 4.1.3.2 Plazo de ejecución:................................................................................................ 43 4.1.4 Interpretación y Desarrollo del Programa............................................................. 43 4.1.5 Trabajos Complementarios..................................................................................... 43 4.1.6 Modificaciones ........................................................................................................ 44 4.1.7 Programa Defectuoso. ............................................................................................ 44 4.1.8 Medios Auxiliares ................................................................................................... 44 4.1.9 Conservación del Programa. .................................................................................. 44 2 ITF51 4.1.10 Recepción del Programa......................................................................................... 44 4.1.10.1 Recepción Provisional:.......................................................................................... 44 4.1.10.2 Licencia y Derechos. ............................................................................................. 45 4.1.10.3 Plazo de Garantía................................................................................................... 45 4.1.10.4 Recepción Definitiva............................................................................................. 45 4.1.11 Contratación de la Empresa Programadora.......................................................... 46 4.1.11.1 Modo de Contratación. .......................................................................................... 46 4.1.11.2 Presentación........................................................................................................... 46 4.1.11.3 Selección. .............................................................................................................. 46 4.1.11.4 Fianza. ................................................................................................................... 46 4.2 Condiciones Económicas. ........................................................................................ 46 4.2.1 Abono del Programa............................................................................................... 46 4.2.2 Precios. .................................................................................................................... 47 4.2.3 Revisión de Precios. ................................................................................................ 47 4.2.4 Penalizaciones......................................................................................................... 47 4.2.5 Contrato................................................................................................................... 47 4.2.6 Responsabilidades................................................................................................... 48 4.2.7 Rescisión del Contrato ............................................................................................ 48 4.2.7.1 Causas de Rescisión. ............................................................................................. 48 4.2.8 Liquidación en el Caso de Rescisión del Contrato. ............................................... 48 4.3 Condiciones Facultativas. ........................................................................................ 49 4.3.1 Personal................................................................................................................... 49 4.4 Condiciones técnicas. ............................................................................................... 49 4.4.1 Requerimientos de Hardware................................................................................. 49 4.4.2 Requerimientos de software.................................................................................... 49 5 Anexos.........................................................................................................50 5.1 Manual de Usuario................................................................................................... 50 5.1.1 Índice del Manual................................................................................................... 51 5.1.2 Introducción............................................................................................................ 52 5.1.3 Requerimientos ....................................................................................................... 52 5.1.4 Descripción de manejo............................................................................................ 52 5.1.4.1 Presentación........................................................................................................... 52 5.1.4.2 PROGRAMA-Ejecutar.......................................................................................... 54 5.1.4.3 PROGRAMA-Paso a Paso .................................................................................... 55 3 ITF51 5.1.4.4 PROGRAMA-Resetear ......................................................................................... 55 5.1.4.5 PROGRAMA-Listar.............................................................................................. 55 5.1.4.6 MEMORIA-Modificar .......................................................................................... 55 5.1.4.7 MEMORIA-Transferir .......................................................................................... 57 5.1.4.8 REGISTROS-Modificar........................................................................................ 57 5.1.4.9 REGISTROS-Listar............................................................................................... 58 5.1.4.10 PUNTO DE RUPTURA-Activar .......................................................................... 58 5.1.4.11 PUNTO DE RUPTURA-Desactivar ..................................................................... 58 5.1.4.12 UTILIDADES-Conversor ..................................................................................... 59 5.1.4.13 UTILIDADES-Color............................................................................................. 59 5.1.4.14 SALIR ................................................................................................................... 60 5.2 Targetería.................................................................................................................. 61 5.2.1 Targeta de Comunicaciones ................................................................................... 61 5.2.1.1 Esquema ................................................................................................................ 61 5.2.1.2 Distribución de los Componentes.......................................................................... 62 5.2.1.3 Detalle de los Jumpers........................................................................................... 62 5.2.1.4 Relación de Componentes ..................................................................................... 63 5.2.2 Targeta Emuladora................................................................................................. 64 5.2.2.1 Esquema ................................................................................................................ 64 5.2.2.2 Distribución de los Componentes.......................................................................... 65 5.2.2.3 Detalle de los Jumpers........................................................................................... 65 5.2.2.4 Relación de Componentes ..................................................................................... 66 5.3 Listado de Programas .............................................................................................. 69 5.3.1 Listado del Programa PC: ...................................................................................... 69 5.3.1.1 Índice de funciones................................................................................................ 69 5.3.2 Listado del Programa para el Microcontrolador 8051........................................ 225 5.4 Protocolo del bus de comunicaciones ................................................................... 252 6 Bibliografía...............................................................................................255 4 ITF51 1 Memoria descriptiva 1.1 Objeto del Proyecto Este proyecto consiste en la creación de un software amigable que relacione el usuario con la targeta de emuladora basada en el microcontrolador 8051 de Intel. Este interficie está destinada a facilitar la tarea de depuración de programas mediante diversas herramientas prácticas. 1.2 Titular El titular del presente proyecto es: 1.3 -Nombre: Escola Tècnica Superior d’Enginyeria (E.T.S.E.) Universitat Rovira i Virgili -Dirección: Av. Països Catalans, 26 Campus Sescelades 43007 Tarragona Telf: 977559610 Antecedentes Este trabajo está basado en la ampliación y adecuación de un proyecto de investigación de 1989 llamado: “Kit de Desarrollo para la Familia de Microcontroladores MCSy-51: EMU-51”, cuyo autor, Esteban del Castillo Pérez, es el director de este nuevo proyecto. Lo que se pretendía antaño era que desde una estación de trabajo, basada en un ordenador personal tipo PC XT (estamos hablando de 1989) o superior, se pudiera tener un control de la targeta de desarrollo igual al que se tendría desde el microcontrolador de la propia targeta. Para ello el proyecto constaba de una parte hardware y otra software. La parte hardware la componían básicamente dos componentes, la targeta de comunicaciones y la targeta emuladora. La primera, proposito general, realizaba una comunicación en paralelo en sustitución de una posible comunicación en serie RS232. Esta elección se debió a la consideración del tamaño de los programas que podrían desarrollarse (32KB). La segunda targeta, la emuladora, disponía de un conector para paralelo y otro para serie dependiendo del tipo de comunicación deseada. La parte software estaba compuesta por dos bloques. Un programa monitor que, alojado en una memoria no volátil, controlaba una serie de funciones o servicios a realizar. El segundo bloque era el programa de interficie con el usuario programado en GWBASIC en el que introduciendo comandos en un “shell”, se podía controlar la targeta emuladora, utilizando a su vez el canal de la targeta de comunicaciones. 5 ITF51 1.4 Posibles Soluciones y Solución Adoptada Visto el antecedente previo, se trata aquí de realizar un programa de interficie donde un usuario no tenga que escribir en una linea de comando una lista de instrucciones que hagan trabajar las funciones del programa monitor una a una; y a su vez, que pueda ver más de una pantalla de resultados a la vez. Debido a la falta de drivers para la Targeta de Comunicaciones empleada, y por consiguiente, a una necesidad gestionar las transmisiones mediante lecturas (inportb) y escrituras (outportb), el lenguaje de programación utilizado ha sido C orientado a comandos para DOS. Por lo tanto se ha tenido que crear un sistema de funciones de representación en caracteres para poder crear un sistema de menús desplegables, múltiples ventanas, etc. Del proyecto anterior, se siguen usando tanto la targeta de comunicaciones como la de desarrollo, conteniendo esta el programa monitor con sus servicios asociados. La sustitución de la antigua interficie creada en BASIC por esta nueva, implica un rediseño total en el manejo de las comunicaciones para relacionarse con el programa monitor. 1.5 Descripción general 1.5.1 Hardware 1.5.1.1 Generalidades Se describe aquí las características hardware tanto de la targeta de comunicaciones como de la emuladora. Para los detalles del Pin-Out y del esquema general ver las figuras en el Anexo 5.2. La información sobre el protocolo de comunicaciones del Bus se halla en el Anexo 5.4. Para más detalles consultar el Manual del fabricante del chip 82C55A y el manual original de Intel del mC 8051. 1.5.1.2 Targeta de Comunicaciones - La targeta de comunicaciones, alojada en el PC, requiere un bus ISA, con un slot libre, para ser conectada. Esto podría ser un problema debido a que la mayoría de ordenadores actuales no disponen ya del bus ISA. - El acceso es a través de puertos de entrada/salida mediante simples outportb e inportb. Se pueden seleccionar dos direcciones base 1B0h y 1F0h conmutando dos jumpers. En este caso se ha escojido la dirección 1B0h. 6 ITF51 - Se debe poder interrumpir a la CPU del PC seleccionando, también mediante jumpers, cualquiera de las siguientes interrupciones: INT3, INT4, INT5 e INT7. En este caso se ha desabilitado esta opción. - El bus de comunicaciones es bidireccional de 8 bits, disponiendo de las siguientes tensiones: +5V, +12V y -12V. Las corrientes máximas recomendables son 1A, 500mA y 100mA, respectivamente. El hecho de que aparte de las líneas de comunicación (datos y control) el bus también disponga de unas líneas de alimentación, nos evita la necesidad de tener que conectar una fuente de alimentación exterior, haciendo el sistema de desarrollo menos aparatoso. Con la opción de una comunicación serie este ahorro no hubiera sido posible. Figura 1. Targeta de Comunicaciones 1.5.1.3 Tarjeta Emuladora - Existen cuatro conectores: CN1: 40 pines. Para la conexión con el PC. CN2: 40 pines. Incluye todas las señales del mC , excepto las de RESET, INT0 y 7 ITF51 XTAL1/2. Destinado a la conexión con la targeta de desarrollo. CN3: 10 pines. Para alimentación a targeta de desarrollo comunicaciones serie RS232. CN4: 2 pines. Para la inserción del cristal de cuarzo alternativo. JP4 determina cual es el cristal activo. - Se dispone de un array de 8 diodos LEDs, conectados al PORT1 del mC, a través de un búffer. Son de propósito general. - La interrupción en el mC 8051 queda reservada para la comunicación con el PC. No debe desactivarse ni alterarse su código asociado - Todos los buses están buffereados. - El espacio de memoria se distribuye como sigue: Programa Monitor = 8KB (8000h a 9FFFh) Memoria de Programa = 8KB (0000h a 1FFFh) Puede ampliarse a 32KB (0000h a 3FFFh) Memoria de Datos = 48KB (0000h a BFFFh) Puede ampliarse a 60 KB (0000h a EFFFh) La Memoria de Datos no está contenida en la Tarjeta Emuladora. Si se requiere, debe estar en la Targeta de Desarrollo. - La ejecución del código de programa es en tiempo real, sin intervención del Emulador. Se dispone de un punto de ruptura. - Los archivos que se manejan son los siguientes: Con extensión .TSK para archivos binarios conteniendo código de programas. Con extensión .LST para archivos ASCII conteniendo listado de programas. - Las posiciones de 03h, 04h y 05h así como las comprendidas entre 1FE0h y 1FFFh de la Memoria de Programas quedan reservadas, no debiendo usarse. - La frecuencia de reloj es de 11.059 MHz. Puede cambiarse a cualquier otra que esté en el dominio del mC. (3.5 MHz a 12 MHz) 8 ITF51 - La única precaución especial para su manejo es la prevención contra descargas por energía estática. Figura 2. Targeta Emuladora 1.5.2 Software 1.5.2.1 Generalidades Se comenta en este apartado de software los detalles de la programación de la Targeta de Comunicaciones, del Programa Monitor y del Interfaz de Usuario. También se expone como interaccionan cada bloque con los otros. El grueso del apartado es, como se puede observar, la descripción del software del Programa Interfaz 1.5.2.2 Targeta de Comunicaciones La programación de esta targeta consiste en configurar adecuadamente el dispositivo programable de entrada/salida 82C55A (CHMOS PROGRAMMABLE PERIPHERAL INTERFACE). El modo escogido para comunicarse con la targeta emuladora es el 2. Tal y como expresa la figura 1 se escribe en la Control Word el valor C0h. Esta palabra de 9 ITF51 control está alojada en la dirección Base_82C55+3, es decir, en la 1B3h. Una vez el chip ya ha sido configurado, se puede tener acceso a los puertos de comunicaciones A,B,C, mediante lecturas o escrituras (outportb o inportb) a 1B0h, 1B1h, 1B2h respectivamente. En este proyecto se usa el puerto A de datos/direcciones y el C de control de la comunicación. Figura 3. Configuración Modo 2 del 82C55A 1.5.2.3 El Programa Monitor Toda la comunicación con el microcontrolador se hace a través de unos servicios ofrecidos por el Programa Monitor. Este programa es alojado en una memoria no volátil situada en la Tarjeta Emuladora. El acceso a estos servicios se consigue a través de la interrupción INT0. Esta interrupción queda reservada para el uso exclusivo del Emulador. Las posiciones de memoria a donde se transfiere el control cuando tiene lugar la INT0 corresponden, en este diseño, a un chip de memoria volátil. El programa monitor no puede estar alojado a partir de esa dirección porque las posiciones bajas de la memoria deben quedar libres para programas de usuario. En las posiciones 03h, 04h, y 05h se debe colocar un salto a la posición de entrada del Programa Monitor. Ahora bien, luego de dar corriente al equipo, el 10 ITF51 contenido de estas posiciones de memoria está indefinido. El problema sería aquí el como consigue el Programa Monitor hacerse el control en estas condiciones. Durante un tiempo, determinado por el monoestable IC11, y a partir del instante en que el señal RST se hace uno, la línea de direcciones A15 tiene por valor A15 negada. De esta forma el control se transfiere a la dirección 8000h y no a la 0000h como lo hace normalmente. El mC desconoce este hecho. Para él todo ocurre como si el control se transfiriera a la dirección 0000h. El programa monitor se halla alojado justo a partir de la dirección 8000h. Una vez ganado el control se deben inicializar las direcciones 03h, 04h, y 05h así como activar la interrupción INT0 para que esta interrupción pueda ser procesada. Estos cambios se producen justo al principio del Programa Monitor Hecho esto, el mC entra en un bucle de espera del que solo sale cuando tiene lugar la interrupción INT0. El programa monitor dispone de quince servicios, numerados del cero al catorce. Para hacer uso de cualquiera de ellos se hace lo siguiente: - Provocar la interrupción INT0 - Poner en el bus de comunicaciones el número del servicio solicitado. Esto se hace de una sola vez al escribir el número de servicio en el bus. La línea – OBF- del protocolo activa directamente la interrupción. Ver Anexo 5.4 para detalles del protocolo. Servicio 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Descripción Inicialización Ejecución paso a paso Transferencia desde PC a memoria del Emulador Transferencia desde memoria del Emulador a PC Transferencia de los registros internos del microcontrolador al PC Ejecución del código sin punto de ruptura Transferencia de memoria interna del microcontrolador al PC Transferencia de un byte desde la memoria del Emulador al PC Modificación de una posición de memoria del Emulador Modificación de una posición de memoria interna del microcontrolador Transferencia de un byte desde la memoria interna del microcontrolador al PC Modificación de Registros Especiales Transferencia de Registros Especiales al PC Entretenimiento -bucle de esperaEjecución del código con punto de ruptura Tabla 1. Servicios del Programa Monitor 11 ITF51 Servicio 0: Se inicializan indicadores y posiciones de memoria. Luego se pasa a bucle de espera. Servicio 1: Se recibe la dirección de memoria en donde se aloja la instrucción que pretendemos ejecutar. Luego se ejecuta la instrucción. No se devuelve información. Servicio2: Primeramente se recibe la dirección de origen, luego la de fin y, por último, los datos. Servicio3: Primeramente se recibe la dirección de origen, luego la de fin. Posteriormente se envían al PC los datos. Servicio4: Se envía al PC la siguiente información, por este orden: DPH, DPL, R7 a R0, B, PSW, PCH, PCL, SP, los siguientes tres bytes situados a partir de la dirección apuntada por el Contador de Programa., y ACC. Servicio5: Se recibe la dirección a partir de la cual se deberá iniciar la ejecución del código. El programa Monitor no interfiere en la ejecución del programa hasta que tenga lugar la interrupción INT0. Si durante la ejecución se modifican las posiciones reservadas, puede no ganarse de nuevo el control del mC por parte del Programa Monitor. Servicio6: Se envía al PC toda la información interna del microcontrolador, por este orden: DPH, DPL, PSW, ACC, B, SP, P0, P1, P2, P3, IP, TMOD, TCON, TH0, TL0, TH1, TL1, SCON, SBUF, PCON, PCH, PCL, y el contenido de la memoria interna desde 7Fh hasta 00h. Servicio7: Se recibe la dirección y se devuelve el contenido Servicio8: Se recibe la dirección, luego un dato. Se modifica el contenido de la dirección con el dato. Posteriormente, se lee esa posición y se devuelve el dato leído para comprobación. Servicio9: Igual que el servicio8 pero para memoria interna del mC. Servicio10: Se recibe la dirección y se devuelve el contenido. Servicio11: Se recibe un byte de dirección correspondiente al Registro Especial que se pretende modificar. Luego se recibe el nuevo contenido. Posteriormente se 12 ITF51 devuelve el dato leído desde el Registro Especial modificado, para su comprobación. Servicio12: Se recibe la dirección del Registro Especial y se devuelve su contenido. Servicio13: Se fuerza al programa monitor a entrar en bucle de espera. Servicio14: Se recibe, primero la dirección de ejecución y luego, la dirección de ruptura. A partir de la dirección de ruptura se modifican tres bytes de código que serán sustituidos por una instrucción de salto al Programa Monitor. Posteriormente, el Programa Monitor restaurará el código original. Se presentan 2 posibles problemas: - Si no se alcanza el punto de ruptura, no se restaura el código original. - Si el código modificado se ejecuta como parte del programa principal, se puede perder el control. El primer caso es solucionado por el programa de interface, que por su cuenta, grava los tres bytes de código y los restaura en el momento adecuado. El segundo caso se soluciona insertando tres instrucciones NOP en el código fuente, justo donde se pretenda poner un punto de ruptura. El resto de consideraciones son las mismas que en el servicio5. 1.5.2.4 Interfaz con el Usuario 1.5.2.4.1 Generalidades Se pueden diferenciar el el programa dos grandes bloques: la relación con el Usuario y la gestión de las comunicaciones con el Emulador. La parte que se encarga de la relación con el usuario es la que supone el mayor esfuerzo, ya que se consumen en ella más tiempo y recursos por parte del Programador. Quizá la parte importante del programa, la que realiza un trabajo en si misma, es la de comunicaciones entre Tarjeta de Comunicaciones-Tarjeta Emuladora; pero, el generar un sistema de menús amigable, con accesos prácticos a las ventanas, actualizaciones automáticas de valores de registros y memoria, etc., a lo mejor sea tambien igual de importante y no menos complicado. 13 ITF51 1.5.2.4.2 Emplazamiento y relaciones del Programa Interfaz Tal y como se representa en la siguiente figura4 esta Interfaz sirve de plataforma para que el Usuario, pasando por la Tarjeta de Comunicaciones, se pueda relacionar con la Tarjeta Emuladora. El Usuario por medio del teclado, puede interrelacionarse con el Interfaz y este le devuelve la información por pantalla. El Interfaz utiliza escrituras y lecturas (outportb e inportb) a la posicion base+puerto de la Targeta de Comunicaciones para utilizar sus puertos A (datos) y C (control). La Targeta de Comunicaciones se relaciona con la Emuladora con las señales del puerto C de control IBF(buffer de entrada lleno) y OBF (buffer de salida lleno). Aquí se observa un esquema de lo esmentado: Figura 4. Diagrama de Relaciones de Bloques 14 ITF51 1.5.2.4.3 Listado de funciones Se representa en la siguiente tabla una relación de todas las funciones utilizadas en este programa agrupadas por funcionalidad. En apartados posteriores se comenta cada grupo por separado, haciendo un análisis de las funciones más representativas. FUNCIONES PRINCIPALES void main (void); int inicializacion (u_int *const size_h, u_int *const size_l); void finalizacion (void); void gestion_main (u_int size_h, u_int size_l); FUNCIONES DE INTERRUPCION void inhibir_int_teclado (void); void desinhibir_int_teclado (void); void interrupt (*timer_viejo)(__CPPARGS); void interrupt timer(__CPPARGS); void interrupt (*teclado_viejo)(__CPPARGS); void interrupt teclado(__CPPARGS); FUNCIONES DE GESTION DE MENUS void menu_principal (char codigo); void menu_ejecutar (char codigo); void menu_registros (char codigo); void menu_memoria (char codigo); void menu_mem_programa (char codigo); void menu_mem_datos (char codigo); void menu_mem_interna (char codigo); void menu_conversor (char codigo); void menu_color (char codigo); FUNCIONES DE GESTION DE ADQUISICION void gestion_leer_car (u_int codigo); void gestion_leer_bin (u_int codigo); void gestion_leer_dec (u_int codigo); void gestion_leer_hex (u_int codigo); FUNCIONES DE REPRESENTACION void ini_pantalla (void); void representar_conversor (void); void representar_menu (void); void representar_ejecutar (u_char activo); void representar_registros_estatico (int activo); void representar_registros_dinamico (int activo); void representar_memoria_estatico (int activo, int tipo_memoria); void representar_memoria_dinamico (int activo, int tipo_memoria); void representar_punto_ruptura(void); void representar_estado (int opcion); void representar_cuadros (void); void representar_menu_memoria (int activo); 15 ITF51 void representar_menu_conversor (int activo); void representar_color (int activo); void representar_presentacion (void); void fin_seguridad (void); void representar_error (u_char opcion); void representar_ok (u_char opcion); FUNCIONES DE COMUNICACION int sub3320 (int tipo_mem); int sub3140 (void); int sub3100 (void); int ini_com (void); int trans (u_int dat1, u_int dat2, u_int dat3, u_int dat4,\ u_char mem, u_char opcion); int servicio1 (u_char dir_h, u_char dir_l); int servicio2 (u_char ini_h, u_char ini_l, u_char fin_h, u_char fin_l); int servicio4 (void); int servicio5 (u_char dir_h, u_char dir_l); int servicio6 (void); int servicio8 (u_char dir_h, u_char dir_l, u_char dato, u_char mem); int servicio9 (u_char dir, u_char dato); int servicio11 (u_char dir, u_char dato); int servicio14 (u_char dir_h, u_char dir_l, u_char rupt_h, u_char rupt_l); int servicio15 (void); FUNCIONES VARIAS void retardo (int tics); void conversor (char valor); int listado (int PC, char activo); void a4toh (char aalfa[4]); void encontrar_size (FILE *original, u_int *const size_h, u_int *const size_l); void gestion_pausa (u_int codigo); FUNCIONES DE GRAFICOS void escribir_car(int x,int y,char car,int h); void escribir_palabra(int x,int y,char car_str[],int h); void linea (int Xini,int Yini,int Xfin, int Yfin, char car, char atr); void rectangulo (int Xsupiz, int Ysupiz, int Xinfder, int Yinfder, int tipo, char atr); void cambiar_atributo (int x,int y,int h); void escribir_hex (int x, int y, long valor,int inverso); void escribir_dec (int x, int y, long valor); void escribir_bin (int x, int y, long valor); FUNCIONES DE FICHEROS int f_escribir_caracter (int caracter,FILE *f1, int posicion); int f_leer_caracter (FILE *f1, int posicion); Tabla 2. Listado de funciones 16 ITF51 1.5.2.4.4 Gráficos Cabe decir que ha sido imposible el uso de las librerías estárdar de gráficos al no poderse usar dentro de las rutinas de atención a las interrupciones (tiempo y teclado). Por lo tanto se han tenido que crear de nuevo todas las funciones gráficas de apoyo requeridas. La mayoria de estas se hallan en la librería graficos.H Se muestran a continuación algunos ejemplos: - void escribir_car(int X,int Y,char car,int H); Función que dibuja en pantalla (escribiendo directamente sobre el mapa de memoria), en una posición x/y determinada, un carácter con su atributo asociado. - void escribir_palabra(int X,int y,char car_str[],int H); Función que dibuja en pantalla utilizando la funcion de Escribir_Car una cadena de carácteres, en una posición x/y determinada, con su atributo asociado. - void linea (int Xini,int Yini,int Xfin, int Yfin, char car, char atr); Función que dibuja en pantalla utilizando la funcion de Escribir_Car una linea de un mismo carácter, en una posición determinada de la pantalla, con su atributo asociado. - void rectangulo (int Xsupiz, int Ysupiz, int Xinfder, int Yinfder, int tipo, char atr); Función que dibuja un rectangulo dando su esquina superior izquierda y su esquina inferior derecha. - void cambiar_atributo (int X,int Y,int H); Función que dada una posición x/y cambia el atributo por el entrado en la variable H - void escribir_hex (int X, int Y, long valor,int inverso); Rutina que escribe en una determinada posición x,y de la pantalla en valor de un byte en hexadecimal; pudiendo elegir mediante la variable inverso si está con el atributo cambiado o no. - void escribir_dec (int X, int Y, long valor); Rutina que escribe en una determinada posición x,y de la pantalla en valor de un byte en decimal. - void escribir_bin (int X, int Y, long valor); Rutina que escribe en una determinada posición x,y de la pantalla en valor de un byte en decimal. Podemos ver que todas las funciones se pueden posicionar por si mismas en cualquier punto de la pantalla (están pensadas para pantallas de 40x80 caracteres alfanuméricos). También es destacable el hecho que todas representan el/los caracter/es con un atributo (color) elegible, ya sea pasado por argumentos o por variable global. 17 ITF51 1.5.2.4.5 Funciones principales es la primera función a ejecutar en el programa. Su esquema es muy sencillo, pero uno no se debe equivocar, a partir de aquí se desarrolla todo el programa llamando a todas las demás funciones. void main (void) Figura 5. Diagrama de flujo de la función main() Básicamente se trata de llamar a una rutina de inicialización para justo después entrar en un bucle de espera. Es a partir de aquí que la función, dentro de este bucle, espera a que dentro de la interrupción de teclado, en alguna parte, se modifique la variable global “opcion_main” que indicará una petición de comunicación com el emulador; o bien a la espera de que la variable global “fin” adquiera el valor de 2, en cuyo caso se finalizaría la aplicación. while (fin!=2) Se analiza pues el valor de “opcion_main” y también el estado del cursor del programa, para saber más detalles de quién ha llamado a la función de transferencia y con que argumentos. 18 ITF51 Para terminar la aplicación se llama a la función de finalización void finalización (void);, que se encarga de restaurar lo modificado para un correcto cierre del programa. La función void inicialización (void) asigna a todas las variables globales sus valores iniciales y modifica las funciones asociadas a las interrupciones del timer y del teclado.También se encarga de abrir los ficheros de ayuda inicializando todo su contenido Otra de sus tareas es que prepara el programa para la adquisición del nombre del archivo con el que trabajar y deja habilitadas las interrupciones de timer y de teclado. Una vez realizado esto pasa a inicializar la pantalla con todos sus menús, recuadros, etc; para luego seguir con una inicialización de las comunicaciones más un reset del sistema. ini_pantalla (); error=ini_com(); Seguidamente se pasa a hacer una actualización de los registros para luego presentarlos en pantalla. error=trans(0,0,0,0,1,6); representar_registros_dinamico (0); 1.5.2.4.6 Gestión del Teclado La rutina de atención a la interrupción de teclado, void interrupt teclado (__CPPARGS);es responsable de toda la gestión del movimiento del cursor en los menús, así como de la adquisición de datos introducidos por el usuario (caracteres, decimales, hexadecimales, binarios) . Lo primero que se realiza es una lectura del código pulsado en el teclado para así poder averiguar posteriormente que tecla se ha pulsado. Esto consiste en una instrucción de lectura a la dirección 60h. codigo=inportb(0x60); A partir de aquí, , y bajo la condición de no estar en una pausa, miraremos si tenemos activada alguna variable que indique que se está realizando alguna adquisición de datos. En este caso se manda a la ejecución del programa a su rutina de gestión. gestion_leer_car(codigo); gestion_leer_bin(codigo); gestion_leer_dec(codigo); gestion_leer_hex(codigo); 19 ITF51 Seguidamente, si la pausa esta desactivada y no se necesita gestionar ninguna adquisición de datos pasamos a inspeccionar otras posibles acciones. Por ejemplo, al pulsar “ESC” en el menú principal se pasa a la gestión del “Salir S/N”.Pero sobretodo, se selecciona aquí en que menú o situacion (principal, ejecutar, memoria, registros,etc.) está el cursor en esos momentos para enviar el control de la ejecución a su correspondiente función de control. Antes de concluir la rutina de interrupción se procede, si se requiere, a llamar a las funciones de representación, para así mostrar al usuario los cambios producidos por su interacción con el teclado. Se representa aquí un diagrama de la evolución de la ejecución en una interrupción de teclado: Figura 5. Diagrama de flujo de la rutina de atención a la interrupción de teclado 20 ITF51 1.5.2.4.7 Gestión de Menús El sistema de gestión de menús, llamado dentro de la rutina de atención a la interrupción de teclado (véase Fig5-2A), lo componen una variadad de funciones, destinadas cada una al control del movimiento del cursor en cada cuadro o situación respectiva. Todas las funciones consisten en evaluar el código de la tecla pulsada en buscando básicamente tres sucesos. El primero es si se ha pulsado la tecla “ESC”, en cuyo caso el cursor del programa vuelve a la situación anterior en la que estaba, en un menú superior. Si no hay situación anterior ni menú superior al que desplazarse (caso de estar en el menú principal), se procede ha abrir el cuadro de diálogo del “Salir S/N”. El segundo suceso a evaluar es si se ha pulsado cualquier tecla de dirección en cuyo caso, y si es procedente, se efectua un movimiento del cursor en la dirección adecuada. El tercer y último proceso a evaluar es si se a pulsado la tecla “ENTER”. Como es evidente este hecho hace que el programa proceda a ejecutar la operación indicada en el menú o a dar un salto a un siguiente submenú. 1.5.2.4.8 Gestión de Adquisición La Gestión de Adquisición (véase Fig5-2B) está compuesta por cuatro funciones, encargadas cada una de ellas de capturar los datos entrados por el usuario mediante el teclado. La primera, void gestion_leer_car (u_int codigo); gestiona las acciones a hacer para leer los caracteres del nombre del archivo. A su vez una vez adquirido este nombre, abre los archivos para ver si existen o no. En caso negativo se vuelve a pedir otra vez la introducción del nombre del archivo. En el caso de pulsar la tecla “ESC” durante la adquisición de caracteres, se cierra el programa. La segunda función es la void gestion_leer_bin (u_int codigo);. Es una rutina que gestiona las acciones a hacer para leer un valor binario de un byte de tamaño. El resultado de esta adquisición va a parar a la variable funcion.dpl.En el caso de pulsar la tecla “ESC” durante la adquisición de valores, se cierra la función de leer número binario y se redibuja la pantalla tal y como estaba antes de ejecutar la función de leer. En el caso de esta función se vuelve al menú de selección del conversor, que es el único sitio desde el que se pueden introducir números binarios. La tercera, void gestión_leer_dec (u_int código); es la encargada de leer un valor decimal de un byte de tamaño. El resultado de esta adquisición va a parar a la variable funcion.dpl.En el caso de pulsar la tecla “ESC” durante la adquisición de valores, se cierra la función de leer número decimal y se redibuja la pantalla tal y como estaba antes de ejecutar la función de leer. En este caso, y al igual que en la función anterior de leer binario, se vuelve al menú de selección del conversor, que es el único sitio desde el que se pueden introducir números en formato decimal. La cuarta y última función es la void gestión_leer_hex (u_int código);. Es ampliamente la función de adquisición mas veces llamada en el programa. Es usada por ejemplo en la adquisición de direcciones como el punto de ruptura, lugar en la memoria de 21 ITF51 programa a donde transferir datos, la dirección a ejecutar el programa o a realizar un paso etc. En definitiva una rutina muy importante en el global de todo el programa. Gestiona las acciones a hacer para leer un valor hexadecimal de uno o dos byte de tamaño dependiendo de quien llame a la función. El resultado de esta adquisición va a parar a la variables funcion.dph el byte alto y funcion.dpl el byte bajo. En el caso de pulsar la tecla “ESC” durante la adquisición de valores, se cierra la función de leer número hexadecimal y se redibuja la pantalla tal y como estaba antes de ejecutar la función de leer, observando todas las variables que indican donde esta el cursor en ese momento. 1.5.2.4.9 Funciones de Representación El grupo de las Funciones de Representación (véase Fig5-4) se encarga dibujar en pantalla todos los cuadros, menús, submenús, valores, contenidos de memoria...; en definitiva, es el apoyo gráfico para las funciones de Gestión de Menús. Algunas de estas funciones no necesitan el paso de argumentos para su ejecución ya que representan casi siempre los mismos caracteres en la pantalla. Entre estas también están las que, no teniendo ningún argumento, utilizan el valor de alguna variable global de control para cambiar una parte de su representación, como por ejemplo iluminar ciertos valores. Otras funciones requiren del paso de argumentos. Normalmente se trata de las representaciones del movimento del cursor en los diferentes menús. La variable pasada indica donde se encuentra el cursor en esos momentos para así poder iluminarlo (cambiar el atributo). Se exponen a partir de aquí todas las funciones de representación con una breve descipción de cada una de ellas. void ini_pantalla (void); es una rutina llamada desde la función main() después de haberse adquirido el nombre del archivo que contiene el programa. Dibuja toda la pantalla para el momento de la inicialización del programa ITF51. Dibuja todos los recuadros, registros, menús, etc. Aquí es donde se selecciona que se muestra en el cuadro principal (el grande y central) al iniciar. En este caso se representa el listado del programa a partir de la dirección 0. Podría sin embargo mostrar otras cosas, como por ejemplo, el contenido de la memoria de programa. void representar_menu Ini_Pantalla(). Dibuja el (void); es una rutina llamada desde la función menú principal sin dejar activada (con el atributo cambiado) ninguna opción. es una rutina que representa en el cuadro secundario el despliegue del menú de ejecucion o de paso a paso. La variable activo es la que selecciona que opción es la que está activada. void representar_ejecutar (u_char activo); es una rutina que representa en pantalla los caracteres fijos dentro del cuadro de registros (los nombres de los registros, los puntos, la linea, etc). La variable activo selecciona el registro que está activado. Si es 0, entonces no se resalta ningún registro. void representar_registros_estatico (int activo); 22 ITF51 void representar_registros_dinamico (int activo); es una rutina que representa en pantalla los caracteres dinámicos dentro del cuadro de registros (los valores de los registros en hexadecimal). La variable activo selecciona el valor que está activado. Si es 0, entonces no se resalta ningún valor. void representar_memoria_estatico (int activo, int tipo_memoria); es una rutina que representa en el cuadro principal los caracteres fijos del despliegue de la memoria. Dependiendo que página de memoria se esté representando los valores de las direcciones de la memoria varían. La variable activo selecciona si el título del cuadro principal está iluminado. La variable tipo_memoria selecciona en que memoria se está trabajando. void representar_memoria_dinamico (int activo, int tipo_memoria); es una rutina que representa en el cuadro principal los valores en hexadecimal de las direcciones de la memoria escojida. Representa también el código ASCII de los mismos valores. Dependiendo que página de memoria se esté representando los valores del contenido de la memoria varian. La variable activo selecciona el único valor que está iluminado (con el atributo cambiado). La variable tipo_memoria selecciona en que memoria se está trabajando. es una rutina que representa en pantalla los caracteres fijos del cuadro de punto de ruptura así como el valor de este en hexadecimal (2 bytes). void representar_punto_ruptura(void); es una rutina que representa en pantalla el contenido del cuadro de estado del programa, pudiéndose selecionar el modo. void representar_estado (int opción); void representar_cuadros (void); es una rutina que representa en pantalla los rectángulos de todo el programa. es una rutina que representa en el cuadro secundario el despliegue del menú de selección de tipo de memoria. La variable activo es la que selecciona que opción es la que está activada. void representar_menu_memoria (int activo); es una rutina que representa en pantalla los caracteres fijos en el cuadro secundario del menú del conversor. La variable activo es la que selecciona que opción es la que está activada. void representar_menu_conversor (int activo); void representar_conversor (void); es una rutina que representa en pantalla el cuadro del conversor y sus caracteres fijos. es una rutina que representa en pantalla los caracteres fijos en el cuadro secundario del menú del color. La variable activo es la que selecciona que opción es la que está activada. void representar_color (int activo); void representar_presentacion (void); es una rutina que dibuja la pantalla de inicio con el nombre del proyecto y del autor. void representar_error (u_char opcion); es una rutina que dibuja en el cuadro secundario un mensaje de error dependiendo de la variable opcion, a la espera de que se salga de la pausa. void representar_ok (u_char opcion); es una rutina que dibuja en el cuadro secundario un mensaje “correcto” dependiendo de la variable opcion, a la espera de que se salga de la pausa. 23 ITF51 void fin_seguridad (void); es una rutina que dibuja en el cuadro secundario el mensaje de salida (Si o No). es una rutina que dibuja en el cuadro del conversor el valor en decimal, hexadecimal y binario entrado en la variable valor. void conversor (char valor); 1.5.2.4.10 Gestión de Tiempo La rutina de atención a la interrupción de tiempo, void interrupt timer(__CPPARGS); es responsable de toda la gestión de las acciones a realizar durante cada tic (55ms) de reloj. Su funcionamiento está descrito en la siguiente figura: Figura 6. Diagrama de flujo de la rutina de atención a la interrupción de tiempo La primera gestión de la que se encarga es la de una temporización (véase Fig6-2A). Para ello comprueba si se ha desactivado la variable “st.fin”, en cuyo caso se decrementa el 24 ITF51 valor “st.count” (previamente cargado al número de tics deseados por contar). Cuando en algún salto a esta rutina el valor “st.count” valga 0, se devuelve la variable “st.fin” a 1, cerrando así la temporización. if (!st.fin){ st.count--; if (!st.count) st.fin=1; } La segunda gestión realizada es la de si están activadas las animaciones de “COMUNICANDO” (véase Fig6-3A) y de “MARCHA” (véase Fig6-3B). En el primer caso en cada tic (cada entrada a esta atención de interrupción), se modifica el atributo de una letra distinta de la palabra “COMUNICANDO”. En el segundo caso, se modifica el atributo de una letra distinta de “MARCHA” cada 8 tics (animación mas lenta). 1.5.2.4.11 Funciones de Comunicación Esta parte del programa es sobre la que recae la responsabilidad de conseguir un diálogo entre Targeta de Comunicaciones y Targeta Emuladora. Tal i como se expresa en apartado 1.5.2.2, se utiliza el puertoA (dirección de memoria 1B0h) para el envio y recibo de bytes. Cada envio provoca una bajada en el nivel de OBF y cada recibo provoca una restauracion de IBF al nivel alto. La continua inspección de estas dos señales permite a los programas Interfaz (PC) y Monitor (Emulador) coordinar el flujo de las ejecuciones de los programas para que así transcurran en paralelo los dos. Una descordinación entre ambós programas, sería fatal, haciendo necesario un reseteo del sistema para volver a juntar ambas ejecuciones. Para este cometido se han desarrollado tres rutinas de apoyo que son llamadas desde las funciones principales de comunicación (servicios). La primera es la int sub3320 (int tipo_mem);. Es muy importante para el handshake entre programa interface y monitor. Primero espera a que la señal IBF (input buffer full) este a 1. Espera para ello un tiempo de 18 tics como máximo. Si este tiempo expira se devuelve un error. Sinó, el programa prosigue. Es aquí donde se evalua el valor de tipo_mem. Si este es 1, se pone el bit1 del puerto C a 0; si, por el contrario, el valor es 2 o 3, se pone el bit1 a 1. Este segundo bit es el que controla y crea una ruta en el hardware hacia la memoria de programa (1er caso) o hacia la memoria de datos de la targeta de desarrollo (2do y 3er caso). Para más detalles, ver en el Anexo 5.2.2.1 el esquema de la Targeta Ensambladora y comprovar la linea M/C en el multiplexor U12. Todo seguido se hace una lectura del puerto A, provocando un restauración de la linea IBF a 0 (puerto C, bit 5). Esto es muy importante para la perfecta coordinación entre programas Monitor e Interficie. 25 ITF51 Para terminar se vuelve a evaluar de nuevo el valor de tipo_mem. Si este es 1 o 2, se produce un outportb(PORTA,0x00) que provoca una bajada en el nivel de OBF, avisando así al Programa Monitor mediante la interrupción INT0. Figura7 . Diagrama de flujo de la función sub3320 Las siguientes dos rutinas se pueden llamar funciones de comprovación, ya que no ejecutan ningúna escritura ni lectura en el puertoA; por lo tanto se mantienen intactas las líneas IBF y OBF. 26 ITF51 La primera, la int sub3140 (void); se trata de una espera a que el 8051 lea el dato enviado por el PC. Esto se hace comprovando si la línea OBF vuelve a 1. Se espera para ello un máximo de 10 tics de reloj. Si expira el tiempo se retorna con error. while ((!st.fin)&&!(xn&0x80)) xn=inportb(PORTC); La segunda, la int sub3100 (void); al contrario de la anterior se trata de una espera a que el 8051 envie un dato destinado para el PC. Esto se hace comprovando que la linea IBF se ponga a 1. Se espera para ello un máximo de 10 tics de reloj. Si expira el tiempo se retorna con error. while ((!st.fin)&&!(xn&0x20)) xn=inportb(PORTC); Figura8. Diagrama de flujo de las funciones sub3140 y sub3100 27 ITF51 Una vez ya comentadas las rutinas de apoyo en las transmisiones, se pasa a comentar el grueso de las Funciones de Comunicación. La mayoria de este grupo de funciones son llamadas desde el bucle de espera del programa principal void main (void); (véase Fig5), debido a que no es posible llamarlas dentro de ningún servicio a interrupción por su demora en el tiempo. La primera función a analizar es la Int Ini_Com (Void); Consiste básicamente en una rutina de inicialización y reseteo de todo el sistema. Figura9. Diagrama de flujo de la función ini_com Para empezar activa el puerto de comunicaciones como bidireccional. Esto se produce al enviar la linea outportb(CONTROL_WORD,0xC0); , que configura la palabra de control del 8255 dejándolo este en modo 2. 28 ITF51 Todo seguido se provoca un flanco en la línea de RESET (port C, pin0) outportb(PORTC,0xFC); outportb(PORTC,0xFD); , para pasar luego a usar el servicio 0 del Programa Monitor, que, como se ha dicho en apartados anteriores, inicializa indicadores y posiciones de memoria. Se expone a continuación el desarrollo y comentarios de la función principal de la comunicación, la int trans (u_int dat1, u_int dat2, u_int dat3, u_int dat4, u_char mem, u_char opcion);. Desde esta rutina se gestionan todos los servicios del Programa Monitor requeridos. El argumento opcion selecciona la subrutina con el servicio a llamar. Consta también de una variable mem que selecciona el tipo de memoria con la que tratar (código o datos) y 4 variables de entrada de datos usadas de diferentes modos en cada subrutina. Se exponen aquí el listado de servicios programados por el Programa de Interficie. int servicio1 (u_char dir_h, u_char dir_l); Ejecución paso a paso: Figura10 . Diagrama de flujo de la función trans-opción1 29 ITF51 int servicio2 (u_char ini_h, u_char ini_l, u_char fin_h, u_char fin_l){ Modificación de una posición de memoria interna del microcontrolador: Figura11 . Diagrama de flujo de la función trans-opción2 30 ITF51 int servicio4 (void);. Transferencia de los registros internos del microcontrolador al PC Figura12 . Diagrama de flujo de la función trans-opción4 31 ITF51 int servicio5 (u_char dir_h, u_char dir_l); Ejecución del código sin punto de ruptura Figura13 . Diagrama de flujo de la función trans-opción5 32 ITF51 int servicio6 (void); Transferencia de memoria interna del microcontrolador al PC Figura14 . Diagrama de flujo de la función trans-opción6 33 ITF51 int servicio8 (u_char dir_h, u_char dir_l, u_char dato, u_char mem); Modificación de una posición de memoria del Emulador Figura15 . Diagrama de flujo de la función trans-opción8 34 ITF51 int servicio9 (u_char dir, u_char dato); Modificación de una posición de memoria interna del microcontrolador Figura16. Diagrama de flujo de la función trans-opción9 35 ITF51 int servicio11 (u_char dir, u_char dato); Modificación de Registros Especiales Figura17 . Diagrama de flujo de la función trans-opción11 36 ITF51 int servicio14(u_char dir_h, u_char dir_l, u_char rupt_h, u_char rupt_l); Ejecución del código con punto de ruptura (1ra parte) Figura18. Diagrama de flujo de la función trans-opción14 37 ITF51 int servicio15 (void); Ejecución del código con punto de ruptura (2da parte) Figura19 . Diagrama de flujo de la función trans-opción15 1.5.2.4.12 Manipulación de Ficheros Para tal cometido han sido creadas dos funciones, int f_escribir_carácter (int caracter,FILE *f1, int posición); para la escritura y int f_leer_carácter (FILE *f1, int posición); para la lectura. En ambas funciones se les pasa por parámetro un puntero a fichero (ya abierto en la inicialización) y un entero indicando la posición en el fichero a tratar. 1.5.2.4.13 Funciones Varias Se exponen aquí una serie de rutinas que, por su naturaleza y funcionalidad, no se pueden incluir en ninguno de los apartados anteriores void retardo (int tics); es una rutina que paraliza el programa principal durante tics/18 segundos. (Las interrupciones siguen activas). Esto lo hace actualizando las variables globales st.count y st.fin, que son usadas dentro de la interrupción de tiempo. Void Encontrar_Size (FILE *Original, U_int *Const Size_H, U_int *Const\ Size_L); es una rutina que dado un fichero, apuntado por la variable original, devuelve su tamaño, expresado en los 2 bytes size_h y size_l. Esto se hace sencillamente recorriendo todo el fichero hasta encontrar el “fin de fichero”. 38 ITF51 Void Gestión_Pausa (U_int Código); es una rutina llamada dentro del servicio a la interrupción del teclado. Gestiona las acciones que hacer al volver de la pausa. Dependiendo donde este el cursor en cada momento repesenta en pantalla diferentes cosas. es una rutina que lista el programa en el cuadro principal a partir de la posición indicada por el contador de programa (PC). La variable activo indica si la primera linea que contiene una instrucción esta iluminada (con el atributo cambiado). Si la dirección a buscar no se encuentra, se decrementa la dirección y se realiza otra búsqueda. Esta búsqueda se realiza como mucho tres veces (3 bytes es el máximo tamaño de una instrucción maquina). Si finalmente la dirección a buscar no es encontrada se devuelve un mensaje de error. Int Listado (Int PC, Char Activo); Para más detalles de esta función ver todos los comentarios en el código. es una rutina que toma una cadena de 4 caracteres como un número en hexadecimal y lo convierte a un entero. El resultado es devuelto en la variable global list.direccion . Void A4toH(Char Alfa[4]); 39 ITF51 2 Presupuesto Trabajo Horas de programación Cantidad (horas) 700 40 Precio/Hora (€) 24 Total (€) 16800 TOTAL 16800 ITF51 3 Conclusiones La realización de este proyecto ha supuesto la dedicación de medio año de trabajo. En un primer momento se intentó plantear el crear el programa interfaz mediante la proramación en lenguaje C++Builder. Este hubiese facilitado, mediante una multitud de clases ya creadas, la creación de una aplicación medianamente compleja para Windows en poco tiempo. Esta opción de programación se desestimó pero, debido al poco acceso a bajo nivel que podía ofrecer este lenguaje. Se ha requerido un acceso a las posiciones de memoria que representan la Targeta de Comunicaciones. Esto ha provocado que se eligiera un entorno C de programación con una pantalla alfanumérica (80 por 40 caracteres). Un entorno en C++Builder hubiese requerido de unos “drivers” que no se poseen para establecer las comunicaciones con la Targeta. Por todo ello, se empezó este proyecto con la creación de una serie de funciones de apoyo gráfico con las que trabajar en todo el programa. Han sido diseñadas para trabajar dentro de rutinas de atención a las interrupciones. Todas llevan como parámetros la dirección x-y de la pantalla donde trabajar y el atributo que usar (el color). Después ya se paso a la creación del entorno en si. Partiendo de que el programa interfaz anterior (programado en GWBASIC), se basaba en una línea de comandos, se ha procurado crear un entorno lo mas amigable posible. El menú principal ya está completamente desplegado desde el principio, lo que facilita una rápida comprensión de toda la capacidad de actuación del programa. También se ha diseñado un cuadro de registros internos, que este siempre visible y actualizado, hecho que facilita mucho la faena al usuario, al no tener que ir buscando siempre en los menús que se abra y refresque el cuadro de registros. Como todo programa interfaz con un emulador se ha tenido que diseñar una representación de la memoria del emulador así como un listado de instrucciones del programa a cargar en él. Esto se realiza alternativamente en un cuadro principal. También se ha creido oportuno y de utilidad el dotar al programa de un conversor de representaciones, hexadecimal, decimal, binario. Cualquier valor sobre el que este el cursor en cada momento se verá representado en sus multiples formas en el cuadro del conversor. Una vez ya se ha tenido el entorno de interfaz bastante terminado, se ha procedido a la creación de las rutinas de comunicación con el emulador. Este proceso ha sido quizá de los más complicados. Se ha tenido que seguir todo el “handshake” entre targetas de Comunicaciones y Emuladora al detalle, comprovando todos los pasos, señal a señal, para la resolución de todos los problemas surgidos. La mayoria de estos problemas surgían de la diferencia de velocidades de ejecución en cada medio (el PC al ir mucho más rapido siempre tiene que ir esperando al Emulador). Una vez todo ya realizado se ha tenido que recomprobar todas las aplicaciones del programa desde un punto de vista del usuario para adecuarlas a las posibles necesidades que pueden surgir en su uso. Este hecho hizo reacer más de una aplicación, reprogramándola casi toda de nuevo. El resultado es un programa interfaz no comerciable, debido a su desfase con los procesadores actuales, pero que ha servido a su programador para aprender a manejar y a diseñar todo un entorno de una aplicación, y aprender a seguir un protocolo de comunicaciones con todo el estudio y comprensión que ello implica. 41 ITF51 4 Pliego de Condiciones 4.1 Generalidades 4.1.1 Condiciones Generales El presente pliego de condiciones tiene como objetivo definir a la empresa programadora el alcance del trabajo y la ejecución cualitativa del mismo. El trabajo informática consistirá en la creación del programa y todas las pruebas oportunas para asegurar la fiabilidad del mismo. El alcance del trabajo de las empresa Programadora incluye el diseño y preparación de todo el material necesario para la adquisición e instalación del programa. 4.1.2 Reglamentos y Normas. Todas las unidades del programa se ejecutarán cumpliendo las prescripciones indicadas en los Reglamentos y Normas Técnicas de obligado cumplimiento para este tipo de instalaciones, tanto de ámbito nacional, autonómico como municipal, así como, todas las otras que se establezcan en la Memoria Descriptiva. Se adaptarán además, a las presentes condiciones particulares que complementarán las indicadas por los Reglamentos y Normas citadas. 4.1.3 Ejecución del Programa 4.1.3.1 Comienzo: La Empresa Programadora comenzará a crear el programa en el termino que figura en el contrato establecido con la Empresa Usuaria, o en su defecto a los quince días de la adjudicación definitiva o la firma del contrato. La Empresa Programadora está obligada a notificar por escrito o personalmente en forma directa a la Empresa Usuaria la fecha de comienzo de la realización del Programa. 42 ITF51 4.1.3.2 Plazo de ejecución: El programa se ejecutará en el término que se estipule en el contrato suscrito con la Empresa Usuaria o en su defecto en el que figure en las condiciones de este pliego. Cuando la Empresa Programadora, de acuerdo, con alguno de los extremos contenidos en el presente Pliego de Condiciones, o bien en el contrato establecido con la Empresa Usuaria, solicite una inspección para poder realizar algún trabajo ulterior que esté condicionado por la misma, vendrá obligada a tener preparada para dicha inspección, una cantidad de obra que corresponda a un ritmo normal de trabajo. Cuando el ritmo de trabajo establecido por el Contratista, no sea normal, o bien a petición de una de las partes, se podrá convenir una programación de inspecciones obligatorias de acuerdo con el plan de obra. 4.1.4 Interpretación y Desarrollo del Programa. La interpretación técnica del Programa, corresponde al Técnico Director. La Empresa Programadora está obligada a someter a éste a cualquier duda, aclaración o contradicción que surja durante la ejecución del Programa por causa de una mala interpretación, o circunstancias ajenas, siempre con la suficiente antelación en función de la importancia del asunto. La Empresa Programadora se hace responsable de cualquier error de la ejecución motivada por la omisión de ésta obligación y consecuentemente deberá rehacer a su costa los trabajos que correspondan a la correcta interpretación del Proyecto. La Empresa Programadora está obligada realizar todo cuanto se necesario para la buena ejecución del Programa, aún cuando no se halle explícitamente expresado en el Pliego de Condiciones o en los documentos del Proyecto. La Empresa Programadora notificará por escrito o personalmente en forma directa al Técnico Director y con suficiente antelación las fechas en que quedarán preparadas para inspección, cada una de las partes del Programa para las cuales se ha indicado la necesidad o conveniencia de las mismas. 4.1.5 Trabajos Complementarios. La Empresa Programadora tiene la obligación de realizar todos los trabajos complementarios que sean indispensables para ejecutar cualquier parte del Programa especificadas en cualquiera de los documentos del Proyecto, aunque en el, no figuren explícitamente mencionadas dichos trabajos complementarios. Todo ello sin variación del importe contratado. 43 ITF51 4.1.6 Modificaciones La Empresa Programadora está obligada a realizar los trabajos que se le encarguen resultantes de modificaciones del Programa, tanto en aumento como disminución o simplemente variaciones, siempre y cuando el importe de las mismas no altere en más o menos de un 25% del valor contratado. La valoración de las mismas se hará de acuerdo, con los valores establecidos en el presupuesto entregado por la Empresa Programadora y que ha sido tomado como base del contrato. El Técnico Director del Programa está facultado para introducir las modificaciones de acuerdo con su criterio, en cualquier parte del Programa, durante la creación, siempre que cumplan las condiciones técnicas referidas en el Proyecto y de modo que ello no varíe el importe total del Programa. 4.1.7 Programa Defectuoso. Cuando la Empresa Programadora halle cualquier parte del Programa defectuosa que no se ajuste a lo especificado en el Proyecto o en este Pliego de Condiciones, el Técnico Director podrá aceptarlo o rechazarlo; en el primer caso, éste fijará el precio que crea justo con arreglo a las diferencias que hubiera, estando obligada la Empresa Programadora a aceptar dicha valoración, en el otro caso, se reconstruirá a expensas de la Empresa Programadora la parte mal ejecutada sin que ello sea motivo de reclamación económica o de ampliación del plazo de ejecución. 4.1.8 Medios Auxiliares Serán de la Empresa Programadora todos los medios y máquinas auxiliares que sean necesarias para la ejecución del Programa. 4.1.9 Conservación del Programa. Es obligación de la Empresa Programadora la conservación en perfecto estado del programa hasta la fecha de recepción definitiva por la Empresa Usuaria, y corren a su cargo los gastos derivados de ello. 4.1.10 Recepción del Programa. 4.1.10.1 Recepción Provisional: Una vez terminado el Programa, tendrá lugar la recepción provisional y para ello se practicará en ellas un detenido reconocimiento por el Técnico Director y la Empresa 44 ITF51 Usuaria en presencia de la Empresa Programadora, levantando acta y empezando a correr desde ese día el plazo de garantía si se halla en estado de ser admitido. De no ser admitido se hará constar en el acta y se darán instrucciones a la Empresa Programadora para subsanar los defectos observados, fijándose un plazo para ello, expirando el cual se procederá a un nuevo reconocimiento a fin de proceder a la recepción provisional. 4.1.10.2 Licencia y Derechos. Una vez efectuada la recepción provisional se le entregará a la Empresa Usuaria una licencia de derecho de uso del programa, una copia del Programa y un Manual de Instalación y Uso. Esta licencia da derecho a instalar el programa en un ordenador. Por cada licencia de derecho de uso que se disponga, sólo puede haber una copia en uso, es decir instalada en un ordenador. No se podrá copiar, instalar en otro ordenador, ejecutar en público o alquilar la copia entregada del programa sin la previa autorización de la Empresa Programadora. Si se quiere instalar el Programa en otro ordenador se tendrá que desinstalar previamente del primero. El Programa solo se puede vender, tal cual, sin modificarlo, completamente con la licencia de derecho de uso del Programa, la copia del Programa y el Manual de Instalación y Uso. 4.1.10.3 Plazo de Garantía. El plazo de garantía será como mínimo de un año, contado desde la fecha de la recepción provisional, o bien el que se establezca en el contrato también contado desde la misma fecha. Durante este período queda a cargo de la Empresa Programadora la conservación del Programa y el arreglo de los errores observados. 4.1.10.4 Recepción Definitiva. Se realizará después de transcurrido el plazo de garantía de igual forma que la provisional. A partir de esta fecha cesará la obligación de la Empresa Programadora de conservar y reparar a su cargo los defectos observados. 45 ITF51 4.1.11 Contratación de la Empresa Programadora. 4.1.11.1 Modo de Contratación. El conjunto del Programa lo realizará la empresa escogida por concurso-subasta. 4.1.11.2 Presentación. Las empresas seleccionadas para dicho concurso deberán presentar sus proyectos en sobre lacrado, antes del 15 de Febrero de 2002 en el domicilio de la Empresa Usuaria. 4.1.11.3 Selección. La empresa escogida será anunciada la semana siguiente a la conclusión del plazo de entrega. Dicha empresa será escogida de mutuo acuerdo entre la Empresa Usuaria y el Director Técnico, sin posible reclamación por parte de las otras empresas concursantes. 4.1.11.4 Fianza. En el contrato se establecerá la fianza que la Empresa Programadora deberá depositar en garantía del cumplimiento del mismo, o, se convendrá una retención sobre los pagos realizados a cuenta de Programa realizado. De no estipularse la fianza en el contrato se entiende que se adopta como garantía una retención del 5% sobre los pagos a cuenta citados. En el caso de que la Empresa Programadora se negase a hacer por su cuenta los trabajos para ultimar el Programa en las condiciones contratadas, o a atender la garantía, la Empresa Usuaria podrá ordenar ejecutarlas a un tercero, abonando su importe con cargo a la retención o fianza, sin perjuicio de las acciones legales a que tenga derecho la Empresa Usuaria si el importe de la fianza no bastase. La fianza retenida se abonará a la Empresa Programadora en un plazo no superior a treinta días una vez firmada el acta de recepción definitiva del Programa. 4.2 Condiciones Económicas. 4.2.1 Abono del Programa. En el contrato se deberá fijar detalladamente la forma y plazos que se abonarán las partes realizadas del Programa. Las liquidaciones parciales que puedan establecerse tendrán carácter de documentos provisionales a buena cuenta, sujetos a las certificaciones 46 ITF51 que resulten de la liquidación final. No suponiendo, dichas liquidaciones, aprobación ni recepción del trabajo que comprenden. Terminado el Programa se procederá a la liquidación final que se efectuará de acuerdo con los criterios establecidos en el contrato. 4.2.2 Precios. La Empresa Programadora presentará, al formalizarse el contrato, relación de los precios de las unidades del Programa que integran el proyecto, los cuales de ser aceptados tendrán valor contractual y se aplicará a las posibles variaciones que puedan haber. Estos precios unitarios, se entiende que comprenden la ejecución total de la unidad del Programa, incluyendo todos los trabajos aún los complementarios y los materiales así como la parte proporcional de imposición fiscal, las cargas laborales y otros gastos repercutibles. En caso de tener que realizarse unidades de Programa no previstas en el proyecto, se fijará su precio entre el Técnico Director y la Empresa Programadora antes de iniciar el Programa y se presentará a la Empresa Usuaria para su aceptación o no. 4.2.3 Revisión de Precios. En el contrato se establecerá si la Empresa Programadora tiene derecho a revisión de precios y la fórmula a aplicar para. calcularla. En defecto de esta última, se aplicará a juicio del Técnico Director alguno de los criterios oficiales aceptados. 4.2.4 Penalizaciones. Por retraso en los plazos de entrega del Programa, se podrán establecer tablas de penalización cuyas cuantías y demoras se fijarán en el contrato. 4.2.5 Contrato. El contrato se formalizará mediante documento privado, que podrá elevarse a escritura pública a petición de cualquiera de las partes. Comprenderá la adquisición de todos los materiales, transporte, mano de obra, medios auxiliares para la ejecución del Programa proyectado en el plazo estipulado, así como la reconstrucción de las unidades defectuosas, la realización de las partes complementarias y las derivadas de las modificaciones que se introduzcan durante la ejecución, éstas últimas en los términos previstos. 47 ITF51 La totalidad de los documentos que componen el Proyecto Técnico del Programa serán incorporados al contrato y tanto el contratista como la Empresa Usuaria deberá firmarlos en testimonio de que los conocen y aceptan. 4.2.6 Responsabilidades. La Empresa Programadora es la responsable de la ejecución del Programa en las condiciones establecidas en el proyecto y en el contrato. Como consecuencia de ello vendrá obligado a la eliminación de lo mal ejecutado y a su reconstrucción correctamente sin que sirva de excusa el que el Técnico Director haya examinado y reconocido el Programa. La Empresa Programadora es la única responsable de todas las contravenciones que ella o su personal cometan durante la ejecución del Programa u operaciones relacionadas con el mismo. También es responsable de los daños que por errores, inexperiencia o empleo de métodos inadecuados se produzcan en la Empresa Usuaria. la Empresa Programadora es la única responsable del incumplimiento de las disposiciones vigentes en la materia laboral respecto de su personal. 4.2.7 Rescisión del Contrato 4.2.7.1 Causas de Rescisión. Se consideraran causas suficientes para la rescisión del contrato las siguientes: · Primero: Muerte o incapacitación de La Empresa Programadora. · Segunda: La quiebra de la Empresa Programadora. · Tercera: Modificación del proyecto cuando produzca alteración en más o menos 25% del valor contratado. · Cuarta: Modificación de las unidades de Programa en número superior al 40% del original. · Quinta : La no iniciación de la programación en el plazo estipulado cuando sea por causas ajenas a la Empresa Programadora. · Sexta : La suspensión de la programación ya iniciada siempre que el plazo de suspensión sea mayor de seis meses. · Séptima: Incumplimiento de las condiciones del Contrato cuando implique mala fe. · Octava : Terminación del plazo de ejecución del Programa sin haberse llegado a completar éste. · Novena : Actuación de mala fe en la ejecución de los trabajos. · Décima: Destajar o subcontratar la totalidad o parte del Programa a terceros sin la autorización del Técnico Director y la Empresa Usuaria. 4.2.8 Liquidación en el Caso de Rescisión del Contrato. 48 ITF51 Siempre que se rescinda el Contrato por causas anteriores o bien por acuerdo de ambas partes, se abonará a la Empresa Programadora las unidades de Programa ya terminadas. Cuando se rescinda el contrato llevará implícito la retención de la fianza para obtener los posibles gastos de conservación del período de garantía y los derivados del mantenimiento hasta la fecha de nueva adjudicación. 4.3 Condiciones Facultativas. 4.3.1 Personal. La Empresa Programadora tendrá al frente de la realización del Programa un encargado con autoridad sobre los demás operarios y conocimientos acreditados y suficientes para la ejecución del Programa. El encargado recibirá, cumplirá y transmitirá las instrucciones y ordenes del Técnico Director de la obra. La Empresa Programadora tendrá el número y clase de operarios que haga falta para el volumen y naturaleza de los trabajos que se realicen, los cuales serán de reconocida aptitud y experimentados en el oficio. La Empresa Programadora estará obligada a separar de la programación, a aquel personal que a juicio del Técnico Director no cumpla con sus obligaciones, realice el trabajo defectuosamente, bien por falta de conocimientos o por obrar de mala fe. 4.4 Condiciones técnicas. 4.4.1 Requerimientos de Hardware. Para que el Programa pueda funcionar con cierta agilidad se aconseja tener como mínimo el siguiente Hardware: PC 386 con coprocessador a 66 Mhz como mínimo 8 Mb de RAM como mínimo 1Mb de espacio libre en el disco duro.. Monitor SVGA con una resolución de 800 * 600 píxeles como mínimo. 4.4.2 Requerimientos de software Para que pueda funcionar el Programa se tendrá que tener instalado en el ordenador como mínimo el Software siguiente: MS-DOS (cualquier versión) 49 ITF51 5 Anexos 5.1 Manual de Usuario Figura20 . ITF51-Pantalla de Presentación 50 ITF51 5.1.1 Índice del Manual 5.1.2 Introducción............................................................................................................ 52 5.1.3 Requerimientos ....................................................................................................... 52 5.1.4 Descripción de manejo............................................................................................ 52 5.1.4.1 Presentación........................................................................................................... 52 5.1.4.2 PROGRAMA-Ejecutar.......................................................................................... 54 5.1.4.3 PROGRAMA-Paso a Paso .................................................................................... 55 5.1.4.4 PROGRAMA-Resetear ......................................................................................... 55 5.1.4.5 PROGRAMA-Listar.............................................................................................. 55 5.1.4.6 MEMORIA-Modificar .......................................................................................... 55 5.1.4.7 MEMORIA-Transferir .......................................................................................... 57 5.1.4.8 REGISTROS-Modificar........................................................................................ 57 5.1.4.9 REGISTROS-Listar............................................................................................... 58 5.1.4.10 PUNTO DE RUPTURA-Activar .......................................................................... 58 5.1.4.11 PUNTO DE RUPTURA-Desactivar ..................................................................... 58 5.1.4.12 UTILIDADES-Conversor ..................................................................................... 59 5.1.4.13 UTILIDADES-Color............................................................................................. 59 5.1.4.14 SALIR................................................................................................................... 60 51 ITF51 5.1.2 Introducción El presente manual explica el modo de utilización del programa ITF51. Está enfocado a usuarios con algún conocimiento previo sobre microcontroladores. Se irán describiendo las diferentes opciones a escoger en cada menú, mostrando en figuras todos los pasos necesarios para una correcta comprensión de su uso. 5.1.3 Requerimientos El único requerimiento hardware para la correcta ejecución del programa es que el ordenador tenga un slot libre en un bus ISA. En cuanto a requerimientos software se necesita crear un directorio C:\ITF51\ que tendrá que contener los siguientes archivos (todo facilitado en el CD de instalación): - ITF51.EXE - MDAT.BIN - MINT.BIN - MPRO.BIN - NOFILE.LST - NOFILE.TSK Todos los archivos .TSK y su .LST correspodiente que se deseen utilizar en el programa deberán ser copiados también al directorio C:\ITF51\ 5.1.4 Descripción de manejo 5.1.4.1 Presentación Lo primero que aparece en pantalla después de la presentación es la siguiente Figura21. El programa pide el nombre del archivo .TSK con el que trabajará. Si se desea trabajar sin archivo basta con pulsar la tecla “ENTER” sin haber introducido ningún caracter. En cualquier momento se puede pulsar la tecla “ESC” y el programa se cierra volviendo al DOS. Figura20 . ITF51-Introducción del nombre 52 ITF51 En el caso de no encontrarse el archivo .TSK o el .LST, el programa lo indica en un mensaje de error, para luego volver a pedir el nombre de nuevo. Figura21 . ITF51-Error en el nombre del fichero A partir de aquí ya se pasa a la pantalla del programa. Como se puede ver en la Figura22 de inicio contiene un menú principal, con todas las opciones a realizar; un cuadro principal, que contiene el listado del programa y puede contener además una representación de las memorias del emulador; un cuadro secundario, en estos momentos en blanco, que contendrá los submenús de las diferentes funciones; un cuadro con un conversor decimalhexadecimal-binario, que contiene un valor de un byte representado de tres formas distintas;un cuadro contienendo los registros internos del microcontrolador; un cuadro, que indica si hay un punto de ruptura activado y en que dirección; y otro cuadro que representa el estado de la ejecución del programa en la Targeta Emuladora. Figura22 . ITF51-Pantalla principal Todos los valores numéricos en el programa, excepto los del conversor, están representados y se introducen en hexadecimal. 53 ITF51 El movimiento por todos los menús y submenús se realiza mediante las flechas del cursor. La tecla “INTRO” accepta/ejecuta la opción seleccionada. La tecla “ESC” cancela/retrocede. 5.1.4.2 PROGRAMA-Ejecutar Si se selecciona en el menú principal PROGRAMA-Ejecutar, pueden ocurrir dos cosas. La primera es que no se haya transferido aún el programa en el Emulador y por lo tanto no se puede ejecutar nada. Aparece en el cuadro secundario el siguiente mensaje de error: Figura23 . ITF51-Error-Programa no transferido La segunda es que si que se haya transferido, en cuyo caso se abre en el cuadro secundario el menú siguiente de la Figura24. Se puede elegir entre la opción “Ultima”, que coge como dirección la indicada por el PC (mirar cuadro de registros), y “Nueva”, que permite introducir manualmente la dirección deseada. Figura24 . ITF51-Submenú PROGRAMA-Ejecutar Una vez el programa ya esté en marcha se podrá detener su ejecución de 4 modos distintos: 1-Intentando transferir cualquier dato (memorias, registros, punto de ruptura,etc), en cuyo caso, se procederá a resetear el sistema, debido a que es imposible hacer una transferencia mientras el programa esta en marcha. 2-Seleccionando directamente la opción de reseteo. (PROGRAMA-Resetear). 3-Llegando a un punto de ruptura previamente activado. 4-Seleccionando en el menú principal (REGISTROS-Listar), en cuyo caso el programa se detiene (en pausa) y se pueden leer los valores de los registros en este momento preciso. 54 ITF51 5.1.4.3 PROGRAMA-Paso a Paso Si se selecciona en el menú principal PROGRAMA-Paso a Paso, las consideraciones son las mismas de la opción anterior de ejecutar, teniendo en cuenta que solo se ejecutará en este caso una instrucción. 5.1.4.4 PROGRAMA-Resetear Si se selecciona en el menú principal PROGRAMA-Resetear, se procede a resetear el sistema reinicializando. Se hace tambien un refresco en el cuadro de registros para ver los valores después de un reseteo. Se debe tener en cuenta aquí que el resetar el sistema no borra la memoria de programa del emulador ni tampoco la de datos de la targeta de desarrollo. 5.1.4.5 PROGRAMA-Listar Si se selecciona en el menú principal PROGRAMA-Listar, se habilitará en el cuadro secundario la introducción de la dirección a partir de la cual se lista el programa (2 bytes). Si la dirección entrada sobrepasa el tamaño del programa .TSK se procede a listar a partir de la dirección 0. Figura25 . ITF51-Submenú PROGRAMA-Listar 5.1.4.6 MEMORIA-Modificar Si se selecciona en el menú principal MEMORIA-Modificar, se permitirá al usuario modificar byte a byte el contenido de cualquier memoria. Para ello se abrirá en el cuadro secundario un submenú pudiendo escoger entre diferentes tipos de memoria: de programa, de datos y interna. 55 ITF51 Figura26 . ITF51-Submenú MEMORIA-Modificar Seleccionando cualquiera de ellas se representará en el cuadro principal el contenido de dicha memoria byte a byte junto con su representación en código ASCII. A partir de aquí el usuario se puede desplazar por todo el mapa de memoria mediante el cursor. Para modificar una posición bastará con pulsar “ENTER” sobre el byte deseado. En las memorias de programa y de datos se puede saltar de página usando también las teclas “RePág” y “AvPág” (la memoria interna solo tiene el tamaño de una página). Figura27 . ITF51-Cuadro principal. Memoria de Programa En la representación de la memoria interna solo se podrá modificar desde la dirección 0000h hasta la 007Fh. Para modificar direcciónes a partir de aquí (direcciones de registros internos) se tendrá que proceder a modificar registros, tal y como se comenta más adelante en este manual. 56 ITF51 Figura28 . ITF51-Cuadro principal. Memoria Interna 5.1.4.7 MEMORIA-Transferir Si se selecciona en el menú principal MEMORIA-Transferir, se podrá transferir el programa (archivo .TSK) en la dirección de PC deseada (2 bytes). Normalmente esta dirección será la de 00h. Se abre para ello en el cuadro secundario, la introducción de dicha dirección. No se podrá transferir un programa fuera del espacio de la memoria de código (0000h hasta 1FFFh) o que este ocupe demasiado para que quepa (8KB). Figura29 . ITF51-Submenú MEMORIA-Transferir 5.1.4.8 REGISTROS-Modificar Si se selecciona en el menú principal REGISTROS-Modificar, el cursor se desplazará al cuadro de registros. Se podrá desplazar por los registros pudiendo seleccionar cual se desea modificar pulsando “ENTER”. Se debe tener en cuenta que hay registros protegidos, en cuyo caso el programa no permitirá su modificación; y que hay registros que no será posible modificar todo su contenido (solo algunos bits) debido a que son de control. 57 ITF51 Figura30 . ITF51-Cuadro de Registros 5.1.4.9 REGISTROS-Listar Si se selecciona en el menú principal REGISTROS-Listar, pausa la ejecución del programa que estaba en marcha, y actualiza los valores del cuadro de registros. Si el programa ya estaba detenido no hace nada, ya que los registros ya están actualizados. 5.1.4.10 PUNTO DE RUPTURA-Activar Si se selecciona en el menú principal PUNTO DE RUPTURA-Activar, se permitirá la introducción de un punto de ruptura dejándolo activado. El cursor se desplazará hasta el cuadro del punto de ruptura donde se podrá introducir la dirección deseada (2 bytes) dentro del margen de la memoria de programa (0000h hasta 1FFFh). Figura31 . ITF51-Cuadro de Registros 5.1.4.11 PUNTO DE RUPTURA-Desactivar Si se selecciona en el menú principal PUNTO DE RUPTURA-Desactivar, se anulará el punto de ruptura dejándolo inactivo. En la parte inferior del cuadro, “Activado”/”Desactivado” indican el estado del punto de ruptura. 58 ITF51 5.1.4.12 UTILIDADES-Conversor Si se selecciona en el menú principal UTILIDADES-Conversor, se abrirá en el cuadro secundario un submenú pudiento elegir el tipo de representación del dato entrante a convertir. Se podrá elegir entre entrar un valor en decimal, en hexadecimal o en binario. Sea cual sea la representación escogida el valor entrante será como mucho de 1 byte de tamaño. Figura32 . ITF51-Submenú UTILIDADES-Conversor El resultado de dicha conversión se mostrará en el cuadro del conversor. Figura33 . ITF51-Cuadro del Conversor 5.1.4.13 UTILIDADES-Color Si se selecciona en el menú principal UTILIDADES-Color, se procederá a la selección de colores para todo el programa. Primero se abrirá el submenú de selección del color del fondo. Figura34 . ITF51-Submenú UTILIDADES-Color-Fondo Despúes de la selección del color de fondo se procederá a la selección del color del texto. El programa tiene en cuenta que si los colores de fondo y texto son muy parecidos debe mostrar un mensaje de error. 59 ITF51 Figura35 . ITF51-Submenú UTILIDADES-Color-Texto 5.1.4.14 SALIR Si se selecciona en el menú principal SALIR, entonces se abrirá en el cuadro secundario el submenú de: “Salir: Si o No ?”. Se podrá elegir mediante las teclas “S” y “N” (y también “ESC”). Figura36 . ITF51-Submenú SALIR También se podrá acceder a este submenú estando el cursor en el menú principal y pulsando la tecla “ESC”. 60 ITF51 5.2 Targetería 5.2.1 Targeta de Comunicaciones 5.2.1.1 Esquema Figura37. Esquema de la Tarjeta de Comunicaciones 61 ITF51 5.2.1.2 Distribución de los Componentes Figura38. Distribución de los Componentes en la Tarjeta de Comunicaciones 5.2.1.3 Detalle de los Jumpers - JP1 = ON activa la interrupción 7 del PC JP2 = ON activa la interrupción 5 del PC JP3 = ON activa la interrupción 4 del PC JP4 = ON activa la interrupción 3 del PC - JP5 = ON, JP6 = OFF se selecciona la dirección base 1B0h JP5 = OFF, JP6 = ON se selecciona la dirección base 1F0h 62 ITF51 - JP7 (1-2) = ON, la interrupción se generará externamente JP7 (2-3) = ON, la interrupción se generará desde PC3 (línea –ACK-) 5.2.1.4 Relación de Componentes Chips: U1 82C55A PPI U2 74HC245 Buffer bidireccional U3 74HC00 Puerta NAND U4 74HC04 Puerta inversora U5 74HC30 Puerta NAND C1 a C5 100nF 63V MKT C6 10mF 16V Electrolítico CN1 Conector plano acodado de 40 pines con orejas de extracción Axx – Bxx Bus de expansión del PC Condensadores: Otros: 63 ITF51 5.2.2 Targeta Emuladora 5.2.2.1 Esquema Figura39. Esquema de la Tarjeta Emuladora 64 ITF51 5.2.2.2 Distribución de los Componentes Figura40. Distribución de los Componentes en la Tarjeta Emuladora 5.2.2.3 Detalle de los Jumpers - - JP1 y JP2 indican la capacidad de la memoria de programa: - JP1 (2,3) = ON y JP2 = OFF si el chip es de 8Kb. - JP1 (1,2) = ON y JP2 = ON si el chip es de 32Kb. JP3 = ON indica que hay +5V en pin 1 de CN2 (Vcc 8051). JP3 = OFF indica que el pin 1 de CN2 queda al aire. - JP4 = ON indica que se usa el cristal de cuarzo por defecto (11,059 MHz); el cristal alternativo no debe ser instalado. JP4 = OFF indica que se usa el cristal alternativo, instalado en CN4. 65 ITF51 - - JP5 y JP6 indican el pin del conector CN2 con señal de reloj. - JP5 = ON y JP6 = OFF indica clock en XTAL1 (XTAL2 aire) - JP5 = OFF y JP6 = ON indica clock en XTAL2 (XTAL1 aire) JP7 = OFF indica línea RxD de CN3 desactivada JP7 = ON indica línea RxD de CN3 activada Por defecto los jumpers están así: JP1(2,3)=ON, JP2=OFF, JP3=OFF, JP4=ON, JP5=OFF, JP6=ON, JP7=OFF 5.2.2.4 Relación de Componentes Chips: U1 74HC245 Buffer bidireccional U2 74HC573 Latch activado por nivel U3 27C64 Memoria EPROM U4 D4464C-15L Memoria RAM U5 74HC245 Buffer bidireccional U6 74HC139 Decodificador U7 8031AH-12P Microcontrolador U8 74HC541 Buffer U9 74HC541 Buffer U10 74HC74 Latch tipo D U11 LM555 Timer U12 74HC257 Multiplexor U13 74HC32 Puerta OR U14 74HC00 Puerta NAND U15 74LS08 Puerta AND U16 74HC04 Puerta NOT U17 MC1488 Puerta TX para RS232 U18 MC1489 Puerta RX para RS232 100mF 16V Electrolítico Condensadores: C1 66 ITF51 C2 10mF 16V Electrolítico C3 22pF Cerámico C4 22pF Cerámico C7 a C24 100nF 63V MKT desacoplo C25 100mF 16V Electrolítico C26 47mF 25V Electrolítico C27 10mF 25V Electrolítico R1 10KV R2 1KV R3 3K3V R4 10KV R7 5K6V R8 5K6V R9 5K6V R10 5K6V R11 5K6V R12 5K6V RP1 Array resistiva de 8 x 5K6V RP2 Array resistiva de 8 x 390V RP3 Array resistiva de 8 x 5K6V Resistencias: Todas las resistencias son de ¼ de vatio de potencia y telorancia del 5%. Diodos: D1 1N4448 Señal D2 1N4448 Señal D3 a D10 LEDs de color rojo Conectores CN1 Conector plano de 40 pines CN2 Conector plano de 40 pines con orejas para extracción CN1 Conector plano de 10 pines CN1 Dos pines redondos dorados (pines de zócalo) 67 ITF51 Otros: XTAL Cristal de cuarzo de 11.059 MHz TR1 Transistor BC212B Zócalo de 40 piner redondos para U7 Zócalo de 28 pines redondos para U3 y U4 Un metro de cinta plana terminada con conector plano, de 40 pines, por ambos lados. 20 cm de cinta plana terminada por un extremo con conector plano de 40 pines y por el otro extremo con un conector para inserción en zócalo de 40 pines del tipo Dual In Line. 68 ITF51 5.3 Listado de Programas 5.3.1 Listado del Programa PC: 5.3.1.1 Índice de funciones escribir_car().................................................. 77 escribir_palabra().............................................. 77 linea()......................................................... 77 rectangulo().................................................... 78 cambiar_atributo().............................................. 79 f_escribir_caracter()........................................... 80 f_leer_caracter()............................................... 80 main().......................................................... 81 inicializacion()................................................ 81 finalizacion().................................................. 84 gestion_main().................................................. 84 inhibir_int_teclado()........................................... 92 deshinhibir_int_teclado()....................................... 92 interrupt timer()............................................... 92 interrupt teclado()............................................. 94 menu_principal()................................................ 96 menu_ejecutar()................................................. 105 menu_registros()................................................ 107 menu_memoria().................................................. 112 menu_mem_programa()............................................. 114 menu_mem_datos()................................................ 119 menu_mem_interna().............................................. 125 menu_conversor()................................................ 129 menu_color().................................................... 130 gestion_leer_car().............................................. 145 gestion_leer_bin().............................................. 155 gestion_leer_dec().............................................. 160 gestion_leer_hex().............................................. 165 ini_pantalla().................................................. 177 representar_conversor()......................................... 178 representar_menu().............................................. 178 representar_ejecutar().......................................... 179 69 ITF51 representar_registros_estatico()................................ 180 representar_registros_dinamico()................................ 182 representar_menu_memoria()...................................... 182 representar_memoria_estatico().................................. 183 representar_memoria_dinamico().................................. 185 representar_punto_ruptura()..................................... 187 representar_cuadros()........................................... 188 representar_estado()............................................ 188 representar_menu_conversor().................................... 189 representar_color()............................................. 190 representar_presentacion()...................................... 192 fin_seguridad()................................................. 193 escribir_hex().................................................. 194 escribir_dec().................................................. 196 escribir_bin().................................................. 197 representar_error()............................................. 197 representar_ok()................................................ 198 sub3320()....................................................... 199 sub3140()....................................................... 200 sub3100()....................................................... 201 ini_com()....................................................... 201 trans()......................................................... 202 servicio1()..................................................... 204 servicio2()..................................................... 205 servicio4()..................................................... 206 servicio5()..................................................... 209 servicio6()..................................................... 210 servicio8()..................................................... 211 servicio9()..................................................... 212 servicio11().................................................... 212 servicio14().................................................... 213 servicio15().................................................... 214 retardo()....................................................... 214 conversor()..................................................... 215 listado()....................................................... 215 a4toh()......................................................... 221 encontrar_size()................................................ 222 gestion_pausa()................................................. 222 70 ITF51 Definiciones.H #ifdef__cplusplus /*consideracions sobre el tipus de compilador*/ #define __CPPARGS ... #else #define __CPPARGS #endif #define ARRIBA 72 #define ABAJO 80 #define IZQUIERDA 75 #define DERECHA 77 #define ENTER 28 #define INTRO 28 #define MAS 78 #define MENOS 74 #define REPAG 73 #define AVPAG 81 #define ESC 1 #define S 31 #define N 49 #define IRR 0x20 #define ISR 0x20 #define IMR 0x21 #define N_REGISTROS 32 #define ESPACIO_PROGRAMA 0x1FFF #define ESPACIO_DATOS 0xBFFF #define ESPACIO_INTERNA 0x00FF #define FRECUENCIA 1193182 #define VECT_TIMER /*Hz frecuencia del cristal de excitacion*/ 8 #define VECT_TECLADO 9 #define PORTA 0x1B0 #define PORTB 0x1B1 #define PORTC 0x1B2 #define CONTROL_WORD 0x1B3 #define eoi() outportb(0x20,0x20) 71 ITF51 /*-----------------------------------DEFINICION DE TIPOS DE VARIABLES -------------------------------------*/ typedef unsigned char u_char; typedef unsigned int u_int ; typedef unsigned long u_long; typedef u_char t_registros [N_REGISTROS]; //Tabla de registros typedef u_char bytes_ruptura [3]; //Los 3 bytes despues //del punto de ruptura typedef struct{ u_char count; //Intervalo de ms a contar u_char fin; //Fin de la cuenta }soft_timer; //Referida al timer soft typedef struct{ u_int direccion; //Ayuda al listar el programa }listar; typedef struct{ u_int principal, //Variables que registros, //indican donde conversor, //se encuentra color, //el cursor en memoria, //cada momento mem_programa, //y asi escojer mem_datos, //la gestion mem_interna, //adecuada pag_programa, pag_datos, pag_interna; }menus; typedef struct{ u_char leer_dec, //Funcion leer decimal ON/OFF y gestion leer_hex, //Funcion leer hexadecimal ON/OFF y gestion leer_bin, //Funcion leer binario ON/OFF y gestion leer_car, //Funcion leer caracter ON/OFF y gestion espera, //Gestion del "COMUNICANDO" dinamico x, //Posicion X donde ejecutar la funcion y, //Posicion Y donde ejecutar la funcion dph, //Contenido del byte alto de la funcion dpl, //Contenido del byte bajo de la funcion 72 ITF51 dl; //Contenido del byte temporal }funciones; typedef struct{ u_char dph, dpl; //Bytes alto y bajo de la direccion //del punto de ruptura }punto_de_ruptura; typedef struct{ u_char fichero, dl; //0=OK 1=Sin fichero.TSK 2=Sin fichero.LST //Byte de datos de la comunicacion }comunicacion; /*-----------------------------------DEFINICION DE VARIABLES GLOBALES -------------------------------------*/ FILE *mem_programa,*mem_datos,*mem_interna,*pro_original; //Archivos temporales que representan //en el PC las memorias de codigo, //datos y interna del emulador u_char programa[]="c:\\ITF51\\MPRO.BIN u_char datos[]="c:\\ITF51\\MDAT.BIN "; "; u_char interna[]="c:\\ITF51\\MINT.BIN "; u_char ficheroTSK[]="c:\\ITF51\\ "; u_char ficheroLST[]="c:\\ITF51\\ "; u_char ficheroDAT[]="c:\\ITF51\\ "; u_char ficheroTMP[]="c:\\ITF51\\ "; u_char SW1; // Status Word 1: // |7|6|5|4|3|2|1|0| u_char opcion_main; // -bit0: Pausa 1=On 0=Off // -bit1: 1=Marcha 0=Paro // -bit2: Programa tranferido 1=Si 0=No // -bit3: Punto de ruptura 1=On 0=Off // -bit4: Trabajando sin archivo 1=Si 0=No // -bit5: ------------- // -bit6: ALTGR pulsado 1=Si 0=No // -bit7: SHIFT pulsado 1=Si 0=No //Gestion en el main (fuera de la //interrupcion) de la opcion deseada 73 ITF51 // y las funciones a transmitir. u_char atributo; //Colores del fondo y texto usados u_char atributo_inverso; //en todo el programa u_char fin; //Variable de salida: // 0=Nada, ejecucion en curso // 1=Menu de escojer "Salir? S/N" // 2=Salir y terminar el programa //Tipos ya preestablecidos: soft_timer st; listar list; menus cursor; funciones funcion; punto_de_ruptura p_ruptura; comunicacion com; t_registros tabla_registros; bytes_ruptura byte_ruptura; /*-----------------------------------PROTOTIPOS DE FUNCIONES -------------------------------------*/ // FUNCIONES PRINCIPALES int inicializacion (u_int *const size_h, u_int *const size_l); void finalizacion (void); void gestion_main (u_int size_h, u_int size_l); // FUNCIONES DE INTERRUPCION void inhibir_int_teclado (void); void desinhibir_int_teclado (void); void interrupt (*timer_viejo)(__CPPARGS); void interrupt timer(__CPPARGS); void interrupt (*teclado_viejo)(__CPPARGS); void interrupt teclado(__CPPARGS); // FUNCIONES DE GESTION DE MENUS void menu_principal (char codigo); void menu_ejecutar (char codigo); void menu_registros (char codigo); void menu_memoria (char codigo); void menu_mem_programa (char codigo); 74 ITF51 void menu_mem_datos (char codigo); void menu_mem_interna (char codigo); void menu_conversor (char codigo); void menu_color (char codigo); // FUNCIONES DE GESTION DE ADQUISICION void gestion_leer_car (u_int codigo); void gestion_leer_bin (u_int codigo); void gestion_leer_dec (u_int codigo); void gestion_leer_hex (u_int codigo); // FUNCIONES DE REPRESENTACION void ini_pantalla (void); void representar_conversor (void); void representar_menu (void); void representar_ejecutar (u_char activo); void representar_registros_estatico (int activo); void representar_registros_dinamico (int activo); void representar_memoria_estatico (int activo, int tipo_memoria); void representar_memoria_dinamico (int activo, int tipo_memoria); void representar_punto_ruptura(void); void representar_estado (int opcion); void representar_cuadros (void); void representar_menu_memoria (int activo); void representar_menu_conversor (int activo); void representar_color (int activo); void representar_presentacion (void); void fin_seguridad (void); void escribir_hex (int x, int y, long valor,int inverso); void escribir_dec (int x, int y, long valor); void escribir_bin (int x, int y, long valor); void representar_error (u_char opcion); void representar_ok (u_char opcion); //FUNCIONES DE COMUNICACION int sub3320 (int tipo_mem); int sub3140 (void); int sub3100 (void); int ini_com (void); int trans (u_int dat1, u_int dat2, u_int dat3, u_int dat4,\ u_char mem, u_char opcion); int servicio1 (u_char dir_h, u_char dir_l); int servicio2 (u_char ini_h, u_char ini_l, u_char fin_h, u_char fin_l); 75 ITF51 int servicio4 (void); int servicio5 (u_char dir_h, u_char dir_l); int servicio6 (void); int servicio8 (u_char dir_h, u_char dir_l, u_char dato, u_char mem); int servicio9 (u_char dir, u_char dato); int servicio11 (u_char dir, u_char dato); int servicio14 (u_char dir_h, u_char dir_l, u_char rupt_h, u_char rupt_l); int servicio15 (void); // FUNCIONES VARIAS void retardo (int tics); void conversor (char valor); int listado (int PC, char activo); void a4toh (char aalfa[4]); void encontrar_size (FILE *original, u_int *const size_h,\ u_int *const size_l); void gestion_pausa (u_int codigo); Código 1. Definiciones.H 76 ITF51 Graficos.H /*-------------------------------------------------escribir_car() - escribe en pantalla (en el mapeado de la memoria) un car cter con la posici¢n y atributos (colores, parpadeo) --------------------------------------------------*/ void escribir_car(int x,int y,char car,int h) { char *carac; int total; carac=0xb8000000; y=y*(160); x=2*x; total=x+y; carac=carac+total; *carac=car; carac++; *carac=h; } /*----------------------------------------------------escribir_palabra() - escribe en pantalla (en el mapeado de la memoria) un string con la posici¢n y atributos (colores, parpadeo) -----------------------------------------------------*/ void escribir_palabra(int x,int y,char car_str[],int h){ int i; i=0; while (car_str[i]!=NULL){ escribir_car (x+i,y,car_str[i],h); i++; } } /*-------------------------------------------------linea() - dibuja una linea (horizontal o vertical) dando sus puntos de origen y fin, con un car cter con el atributo (colores, parpadeo) --------------------------------------------------*/ void linea (int Xini,int Yini,int Xfin, int Yfin, char car, char atr){ int temp; if (Xini==Xfin){ //linea vertical for (temp=Yini;temp<=Yfin;temp++) 77 ITF51 escribir_car (Xini,temp,car,atr); } else if (Yini==Yfin){ //linea horizontal for (temp=Xini;temp<=Xfin;temp++) escribir_car (temp,Yini,car,atr); } } /*-----------------------------------------------------rectangulo() - dibuja un rectangulo dando su esquina superior izquierda y su esquina inferior derecha Tipo1:lineas dobles Tipo2:lineas simples Tipo3:Todo relleno (caracter "Null") ------------------------------------------------------*/ void rectangulo (int Xsupiz, int Ysupiz, int Xinfder, int Yinfder, int tipo, char atr) {char caracter[10]; //tabla de todos los caracteres posibles int medio; //linea central en los tipos 2,3,4 int temp1,temp2; //variables para lineas if (tipo!=3){ if (tipo==1){ //lineas simples caracter[0]=218; //esquina superior izquierda caracter[1]=191; //esquina superior derecha caracter[2]=217; //esquina inferior derecha caracter[3]=192; //esquina inferior izquierda caracter[4]=196; //guion horizontal caracter[5]=179; //guion vertical } if (tipo==2){ //lineas dobles caracter[0]=201; //esquina superior izquierda caracter[1]=187; //esquina superior derecha caracter[2]=188; //esquina inferior derecha caracter[3]=200; //esquina inferior izquierda caracter[4]=205; //guion horizontal caracter[5]=186; //guion vertical } escribir_car (Xsupiz,Ysupiz,caracter[0],atr); //esquina supiz escribir_car (Xinfder,Ysupiz,caracter[1],atr); //esquina supder escribir_car (Xinfder,Yinfder,caracter[2],atr); //esquina infiz escribir_car (Xsupiz,Yinfder,caracter[3],atr); //esquina infder temp1=Xsupiz+1; //horizontales sup-inf temp2=Xinfder-1; 78 ITF51 linea (temp1,Ysupiz,temp2,Ysupiz,caracter[4],atr); //horizontales sup-inf linea (temp1,Yinfder,temp2,Yinfder,caracter[4],atr); temp1=Ysupiz+1; temp2=Yinfder-1; linea (Xsupiz,temp1,Xsupiz,temp2,caracter[5],atr); //verticales der-iz linea (Xinfder,temp1,Xinfder,temp2,caracter[5],atr); } if (tipo==3){ temp1=Ysupiz; while (temp1<=Yinfder){ linea (Xsupiz,temp1,Xinfder,temp1,255,atr); temp1++; } } } /*------------------------------------------------------CAMBIAR_ATRIBUTO (int x,int y,int h) - Modifica el atributo de una posicion determinada. -------------------------------------------------------*/ void cambiar_atributo (int x,int y,int h) { char *carac; int total; carac=0xb8000000; y=y*(160); x=2*x; total=x+y; carac=carac+total; carac++; *carac=h; } Código 2. Graficos.H 79 ITF51 Ficheros.H /*------------------------------------------------------------------------------INT F_ESCRIBIR_CARACTER (INT CARACTER,CHAR FICHERO[], INT POSICION); Escribe un caracter (un byte) en una posición determinada de un fichero. -------------------------------------------------------------------------------*/ int f_escribir_caracter (int caracter,FILE *f1, int posicion){ int error=0; rewind(f1); error=fseek (f1,posicion,0); fputc(caracter,f1); rewind(f1); return (error); } /*-----------------------------------------------------------------------------INT F_LEER_CARACTER (CHAR FICHERO[], INT POSICION); Lee un caracter (un byte) en una posición determinada de un fichero. -------------------------------------------------------------------------------*/ int f_leer_caracter (FILE *f1, int posicion){ int error,caracter; rewind(f1); error=fseek (f1,posicion,0); if (error){ error++; } caracter=fgetc(f1); rewind(f1); return (caracter); } Código 3. Ficheros.H 80 ITF51 ITF51.C #include <conio.h> #include <dos.h> #include <stdlib.h> #include <stdio.h> #include "C:\itf51\graficos.h" #include "C:\itf51\ficheros.h" #include "C:\itf51\definiciones.h" /*-----------------------------------VOID MAIN (VOID) Programa principal -------------------------------------*/ void main (void){ u_int error,size_h, size_l; //Tamaño del codigo //a transferir inicializacion(&size_h, &size_l); //Rutina de inicializacion while (fin!=2){ //Mientras no Salir gestion_main(size_h, size_l); //Bucle a la espera de FIN=2 } finalizacion(); } /*-----------------------------------------------INT INICIALIZACION (VOID) Funcion que asigna a todas las variables globales sus valores iniciales y modifica las funciones asociadas a timer y teclado . ------------------------------------------------*/ int inicializacion (u_int *const size_h, u_int *const size_l){ u_char error; //Codigo de error u_int temp; //Variable para calculos textmode(64); //Dimensiones de la pantalla //0-79 columnas, 0-49 filas _setcursortype(_NOCURSOR); //Sin cursor parpadeando st.count=0; //Cargamos el contador de tic a 0 st.fin=1; //Contador parado list.direccion=0; 81 ITF51 cursor.principal=10; cursor.registros=cursor.memoria=cursor.conversor=cursor.color=0; cursor.mem_programa=cursor.mem_datos=cursor.mem_interna=0; cursor.pag_programa=cursor.pag_datos=cursor.pag_interna=0; funcion.leer_car=funcion.leer_dec=funcion.leer_hex=funcion.leer_bin=0; funcion.x=funcion.y=funcion.dph=funcion.dpl=funcion.espera=0; p_ruptura.dph=p_ruptura.dpl=0; com.dl=0; com.fichero=0; atributo=0x1B; //Colores: fondo->azul //texto->cyan claro atributo_inverso=0x31; //Colores: fondo->cyan //texto->azul error=fin=0; opcion_main=0; SW1=0x00; //Aqui abrimos los ficheros de ayuda y cargamos a 0 todo su contenido if ((mem_programa=fopen(programa,"wb+"))==NULL){ //C:\ITF51\MPRO.BIN error=1; return(error); } for(temp=0;temp<=ESPACIO_PROGRAMA;temp++){ //Tamaño 8KB error=f_escribir_caracter(0x00,mem_programa,temp); } if ((mem_datos=fopen(datos,"wb+"))==NULL){ //C:\ITF51\MDAT.BIN error=1; return(error); } for(temp=0;temp<=ESPACIO_DATOS;temp++){ //Tamaño 48KB error=f_escribir_caracter(0x00,mem_datos,temp); } if ((mem_interna=fopen(interna,"wb+"))==NULL){ //C:\ITF51\MPRO.BIN error=1; return(error); } for(temp=0;temp<=ESPACIO_INTERNA;temp++){ //Tamaño FFh bytes error=f_escribir_caracter(0x00,mem_interna,temp); } for(temp=0;temp<32;temp++){ //Toda la tabla de tabla_registros[temp]=0; //registros a 0 82 ITF51 } teclado_viejo=getvect(VECT_TECLADO); //Guardar el servicio de //interrupcion de teclado timer_viejo=getvect(VECT_TIMER); //Guardar el servicio de //interrupcion de tiempo setvect(VECT_TIMER,timer); //Poner el nuevo servicio //de interrupcion de tiempo representar_presentacion(); //Dibujar pantalla inicial while (!kbhit()); //Mientras no se pulse nada rectangulo (0,22,78,49,3,atributo); //Limpiar media pantalla escribir_palabra(23,28,"Introduzca el nombre del archivo:",atributo); escribir_palabra(23,31,ficheroTSK,atributo); funcion.x=32; //Valores de las variables funcion.y=31; //para la funcion de leer funcion.dph=0; //y cursor parpadeante funcion.leer_car=1; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); setvect(VECT_TECLADO,teclado); //Poner el nuevo servicio //de interrupcion de tiempo while (funcion.leer_car); //Mientras se introduzca el nombre if (fin!=2){ //Si no se ha pulsado ESC antes if (!(SW1&0x10)) encontrar_size (pro_original,\ *(&size_h),*(&size_l)); //Si no trabajamos sin archivo ini_pantalla (); //Inicializacion de toda la pantalla error=ini_com(); //Reseteamos el emulador if (!error){ error=trans(0,0,0,0,1,6); //Actualizamos registros representar_registros_dinamico (0); } funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario if (error){ representar_error (3); //"Emulador no responde" SW1=SW1|0x01; //Pausa activada } opcion_main=0; //Restaurar seleccion en main 83 ITF51 } return(0); } /*-------------------------------------------VOID FINALIZACION (VOID) Funcion que restaura las funciones asociadas iniciales (teclado,timer) y limpia la pantalla --------------------------------------------*/ void finalizacion (void){ setvect(VECT_TECLADO,teclado_viejo); //Restaurar el servicio de //interrupcion de teclado setvect(VECT_TIMER,timer_viejo); //Restaurar el servicio de //interrupcion de tiempo fclose(mem_programa); //Cerrar los archivos fclose(mem_datos); //de apoyo fclose(mem_interna); fclose(pro_original); clrscr(); //Limpiar la pantalla } /************************************************************ VOID GESTION_MAIN (U_INT SIZE_H, U_INT SIZE); Bucle de espera dentro del main. Gestiona la llamada a los diferentes servicios de comunicacion ************************************************************/ void gestion_main (u_int size_h, u_int size_l){ u_char ini_h, ini_l, fin_h, fin_l; //Direcciones de inicio //y fin del programa en //la memoria de datos u_int error,temp1,temp2; //Variable del codigo de //error y auxiliares para //calculos y tareas //Comprovamos el IBF (bit5), despues de haver ejecutado el programa. //Esto nos indicara si se ha llegado a el punto de ruptura if (((inportb(PORTC))&0x20)&&((cursor.principal==15)||(cursor.principal==16))\ &&(SW1&0x08)){ error=trans(0,0,0,0,1,15); //Terminamos de realizar la funcion //de ejecucion con p_ruptura error=trans(0,0,0,0,1,6); //Actualizamos registros 84 ITF51 representar_registros_dinamico (0); //Calculamos la direccion en la que se encuentra el PC (PCH+PCL) y listamos temp1=(tabla_registros[22]*256)+tabla_registros[23]; error=listado(temp1,1); SW1=SW1&0xF7; //P_ruptura desactivado representar_punto_ruptura(); funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario if (error){ representar_error(4); //"Transmision Incorrecta" } else if (!error){ representar_ok(9); //"Se ha llegado al p_ruptura" } SW1=SW1&0xFD; //Estado=Paro representar_estado(0); SW1=SW1|0x01; //Pausa activada } if (opcion_main==9){ //Funcion de reseteo if ((SW1&0x08)&&(cursor.principal!=42)){ //P_ruptura activado? SW1=SW1&0xF7; //P_ruptura desactivado representar_punto_ruptura(); temp1=p_ruptura.dph; temp2=p_ruptura.dpl; error=trans(temp1,temp2,byte_ruptura[0],0,1,8);//Restauramos temp2++; //los valores if (temp2>0xff){ //de los 3 bytes temp2=0; //siguientes temp1=temp1+1; //al p_ruptura } error=trans(temp1,temp2,byte_ruptura[1],0,1,8); temp2++; if (temp2>0xff){ temp2=0; temp1=temp1+1; } error=trans(temp1,temp2,byte_ruptura[2],0,1,8); } error=ini_com(); //Reseteamos if (error){ representar_error (3); //"El emulador no responde" } 85 ITF51 else if (!error){ error=trans(0,0,0,0,1,6); //Actualizamos registros if (!error) representar_ok (8); //"Sistema reseteado" else if (error) representar_error (3); //"El emulador no responde" representar_registros_dinamico (0); } SW1=SW1&0xFD; //Estado=Paro representar_estado(SW1&0x02); SW1=SW1|0x01; //Pausa activada funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado listado(0,0); opcion_main=0; //Restaurar seleccion en main } if (opcion_main==1){ if (cursor.registros){ //Si estamos cambiando registros //Hay 4 registros que no se pueden modificar: SP,SBUF,PCH,PCL if ((com.dl==0x81)||(com.dl==0x99)||(com.dl==0xF8)||(com.dl==0xF9)){ representar_registros_estatico (0); representar_registros_dinamico (0); representar_error (8); //"El reg. no se puede modificar" SW1=SW1|0x01; //Pausa activada } else{ representar_registros_estatico (0); error=trans(com.dl,funcion.dpl,0,0,1,11); //Transmitimos un registro if (!error){ tabla_registros[cursor.registros]=com.dl;//Refrescamos en la tabla if (cursor.registros>=24){ //Si el registro es R0-R7 //tambien lo refrescamos //en la memoria interna f_escribir_caracter (com.dl,mem_interna,cursor.registros-24); } representar_registros_estatico (cursor.registros); representar_registros_dinamico (0); funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario representar_ok (4); //"Trans. de registro CORRECTO" SW1=SW1|0x01; //pausa activada } else if (error){ representar_registros_estatico (cursor.registros); 86 ITF51 representar_registros_dinamico (0); funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario representar_error (8); //"El reg. no se puede modificar" SW1=SW1|0x01; //Pausa activada } } } if (cursor.pag_programa){ representar_memoria_estatico (0,1); //Calculamos la direccion de la memoria donde escribir el nuevo byte. //Temp1=byte alto. Temp2=byte bajo. Funcion.dpl=byte(dato) temp1=(cursor.mem_programa+(cursor.pag_programa-1)*256); temp2=temp1&0x00FF; temp1=(temp1&0xFF00)>>8; error=trans(temp1,temp2,funcion.dpl,0,1,8);//Enviar byte a la //memoria de programa funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario if (!error){ f_escribir_caracter (funcion.dpl,mem_programa,(temp1<<8)+temp2); //Refrescamos el byte en la //memoria de programa conversor (funcion.dpl); //Presentacion del valor convertido representar_memoria_dinamico(1,1); representar_ok (5); //"Transmision correcta" SW1=SW1|0x01; //pausa activada } else if (error){ conversor (funcion.dpl); //Presentacion del valor convertido representar_memoria_dinamico(1,1); representar_error (4); //"Transmision incorrecta" SW1=SW1|0x01; //pausa activada } } if (cursor.pag_datos){ representar_memoria_estatico (0,2); //Calculamos la direccion de la memoria donde escribir el nuevo byte. //Temp1=byte alto. Temp2=byte bajo. Funcion.dpl=byte(dato) temp1=(cursor.mem_datos+(cursor.pag_programa-1)*256); temp2=temp1&0x00FF; 87 ITF51 temp1=(temp1&0xFF00)>>8; error=trans(temp1,temp2,funcion.dpl,0,2,8);//Enviar byte a la //memoria de datos funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario if (!error){ f_escribir_caracter (funcion.dpl,mem_datos,(temp1<<8)+temp2); //Refrescamos el byte en la //memoria de datos conversor (funcion.dpl); //Presentacion del valor convertido representar_memoria_dinamico(1,2); representar_ok (5); //"Transmision correcta" SW1=SW1|0x01; //pausa activada } else if (error){ conversor (funcion.dpl); //Presentacion del valor convertido representar_memoria_dinamico(1,2); representar_error (4); //"Transmision incorrecta" SW1=SW1|0x01; //pausa activada } } if (cursor.pag_interna){ representar_memoria_estatico (0,3); //Calculamos la direccion de la memoria donde escribir el nuevo byte. //Temp1=byte alto. Temp2=byte bajo. Funcion.dpl=byte(dato) temp1=(cursor.mem_interna); temp1=temp1&0x00FF; if (temp1<0x80){ error=trans(temp1,funcion.dpl,0,0,1,9); //Enviar byte a la //memoria interna funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario if (!error){ f_escribir_caracter (funcion.dpl,mem_interna,temp1); //Refrescamos el byte en la //memoria interna conversor (funcion.dpl); //Presentacion del valor convertido representar_memoria_dinamico(1,3); if (temp1<=7){ //Si se trata de R0-R7 //refrescamos tambien la //tabla de registros 88 ITF51 tabla_registros[24+temp1]=funcion.dpl; representar_registros_dinamico (0); } representar_ok (5); //"Transmision correcta" SW1=SW1|0x01; //pausa activada } else if (error){ conversor (f_leer_caracter (mem_interna,temp1)); //Presentacion del valor convertido representar_memoria_dinamico(1,3); representar_error (4); //"Transmision incorrecta" SW1=SW1|0x01; //pausa activada } } else if (temp1>=80){ conversor (f_leer_caracter (mem_interna,temp1)); //Presentacion del valor convertido representar_memoria_dinamico(1,3); representar_error (9); //"Solo se puede modificar //desde 00 hasta FF" SW1=SW1|0x01; //Pausa activada } } else if ((cursor.principal==15)||(cursor.principal==16)){ if (!(SW1&0x08)){ //Ejec. sin p_ruptura error=trans(funcion.dph,funcion.dpl,0,0,1,5); funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario if (!error){ representar_ok (6); //"Programa ejecutado" SW1=SW1|0x02; //Estado=Marcha } else if (error){ representar_error (10); //"Ejecucion Incorrecta" } representar_estado(SW1&0x02); SW1=SW1|0x01; //Pausa activada } else{ //Ejec. con p_ruptura temp1=(p_ruptura.dph*256)+p_ruptura.dpl; byte_ruptura[0]=f_leer_caracter (mem_programa,temp1); //Guardamos los byte_ruptura[1]=f_leer_caracter (mem_programa,temp1+1); //3 bytes despues 89 ITF51 byte_ruptura[2]=f_leer_caracter (mem_programa,temp1+2); //del p_ruptura error=trans(funcion.dph,funcion.dpl,p_ruptura.dph,p_ruptura.dpl,1,14); funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario if (!error){ representar_ok (6); //"Programa ejecutado" SW1=SW1|0x02; //Estado=Marcha } else if (error){ representar_error (10); //"Ejecucion incorrecta" SW1=SW1&0xFD; //Estado=Paro } representar_estado(SW1&0x02); SW1=SW1|0x01; //Pausa activada } } else if ((cursor.principal==17)||(cursor.principal==18)){ //Ejecucion Paso a Paso error=trans(funcion.dph,funcion.dpl,0,0,1,1); error=trans(0,0,0,0,0,4); //Refrescamos registros funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario if (!error){ representar_ok (7); //Paso ejecutado SW1=SW1&0xFD; //estado=Paro temp1=((tabla_registros[22]*256)+tabla_registros[23]); temp1=temp1-((ini_h*256)+ini_l); listado(temp1,1); //Nuevo listado de programa } else if (error){ representar_error (11); //"Paso incorrecto" } representar_estado(SW1&0x02); SW1=SW1|0x01; //Pausa activada } opcion_main=0; //Restaurar seleccion en main } if (opcion_main==3){ //Transmision del programa //entero en bloque a la //memoria de programa ini_h=funcion.dph; //Calculamos direcciones 90 ITF51 ini_l=funcion.dpl; //de inicio y fin fin_l=ini_l+size_l; if (!fin_l){ //Se le resta 1 al la direccion fin_l--; //de fin. Si fin_l es 0, entonces fin_h=(fin_l>>8)+ini_h+size_h-1; //se le tiene que restar uno } //tambien a fin_h else if (fin_l){ fin_l--; fin_h=(fin_l>>8)+ini_h+size_h; } temp1=ini_h; temp2=ini_l; temp1=(temp1<<8)+temp2; if (temp1<=ESPACIO_PROGRAMA){ //Si esta dentro del margen error=trans(ini_h,ini_l,fin_h,fin_l,1,2); //Transmision en bloque ini_com(); //Reseteamos desinhibir_int_teclado (); //Habilitamos la INT de teclado funcion.espera=0; //Paramos la animacion "COMUNICANDO" } else if (temp1>ESPACIO_PROGRAMA) error=1; //Fuera del margen if (!error){ representar_ok (1); //"Transmision de programa //correcto" SW1=SW1|0x04; //Programa tranferido SW1=SW1|0x01; //Pausa activada } else if (error){ representar_error (5); //"Direccion de destino //incorrecta" SW1=SW1|0x01; //Pausa activada } opcion_main=0; //Restaurar seleccion en main } if (opcion_main==4){ //Listado de programa temp1=(funcion.dph*256)+funcion.dpl; error=listado(temp1,0); if (error) listado(0,0); //Si la direccion entrada a listar //no se encuentra en el fichero.LST //entonces se lista a partir de 0 opcion_main=0; } if (opcion_main==8){ //Pausa en la ejecucion error=trans(0,0,0,0,1,4); //Listar registros 91 ITF51 funcion.espera=0; //Paramos la animacion "COMUNICANDO" desinhibir_int_teclado (); //Habilitamos la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario SW1=SW1&0xFD; //Programa Parado representar_estado(SW1&0x02); representar_ok (10); //"Programa Detenido" SW1=SW1|0x01; //Pausa activada temp1=(tabla_registros[22]*256)+tabla_registros[23]; listado (temp1,1); //Nuevo listado de programa opcion_main=0; //Restaurar seleccion en main } } /*-------------------------------------------VOID INHIBIR_INT_TECLADO (VOID) Funcion que desactiva la interrupcion de teclado. --------------------------------------------*/ void inhibir_int_teclado (void){ char c; disable(); c=inportb(IMR); c=c|0x02; outportb (IMR,c); enable(); } /*-------------------------------------------VOID DESINHIBIR_INT_TECLADO (VOID) Funcion que activa la interrupcion de teclado. --------------------------------------------*/ void desinhibir_int_teclado (void){ char c; disable(); c=inportb(IMR); c=c&0xFD; outportb (IMR,c); enable(); } /*-------------------------------------------VOID INTERRUPT TIMER (__CPPARGS) Rutina de atencion a la interrupcion de 92 ITF51 tiempo IRQ0. --------------------------------------------*/ void interrupt timer() { if (!st.fin){ //Cuenta 18tics/segundo=55ms st.count--; //Es un retardo simple if (!st.count) st.fin=1; //de st.count tics } //Gestion de la animacion de la palabra "- COMUNICANDO -" //durante cualquier tipo de transmision: if ((funcion.espera)&&(funcion.espera<20)){ escribir_palabra (30,44,"C O M U N I C A N D O",atributo); if (funcion.espera==1) { escribir_palabra (30,44,"C",(atributo_inverso)); escribir_palabra (28,44,"\\",atributo); escribir_palabra (52,44,"\\",atributo); } else if (funcion.espera==2) escribir_palabra (32,44,"O",(atributo_inverso)); else if (funcion.espera==3){ escribir_palabra (34,44,"M",(atributo_inverso)); escribir_palabra (28,44,"³",atributo); escribir_palabra (52,44,"³",atributo); } else if (funcion.espera==4) escribir_palabra (36,44,"U",(atributo_inverso)); else if (funcion.espera==5){ escribir_palabra (38,44,"N",(atributo_inverso)); escribir_palabra (28,44,"/",atributo); escribir_palabra (52,44,"/",atributo); } else if (funcion.espera==6) escribir_palabra (40,44,"I",(atributo_inverso)); else if (funcion.espera==7){ escribir_palabra (42,44,"C",(atributo_inverso)); escribir_palabra (28,44,"Ä",atributo); escribir_palabra (52,44,"Ä",atributo); } else if (funcion.espera==8) escribir_palabra (44,44,"A",(atributo_inverso)); else if (funcion.espera==9){ escribir_palabra (46,44,"N",(atributo_inverso)); escribir_palabra (28,44,"\\",atributo); escribir_palabra (52,44,"\\",atributo); } else if (funcion.espera==10) escribir_palabra (48,44,"D",(atributo_inverso)); else if (funcion.espera==11){ 93 ITF51 escribir_palabra (50,44,"O",(atributo_inverso)); escribir_palabra (28,44,"³",atributo); escribir_palabra (52,44,"³",atributo); } else if (funcion.espera==12) escribir_palabra (50,44,"O",(atributo_inverso)); else if (funcion.espera==13){ escribir_palabra (28,44,"/",atributo); escribir_palabra (52,44,"/",atributo); } else if (funcion.espera==15){ escribir_palabra (28,44,"Ä",atributo); escribir_palabra (52,44,"Ä",atributo); } funcion.espera++; if (funcion.espera>16) funcion.espera=1; } //Gestion de la animacion de la palabra "MARCHA" //durante el tiempo que el programa este en ejecucion if ((funcion.espera>=20)&&(funcion.espera<=68)){ escribir_palabra (71,38,"MARCHA",atributo_inverso); if ((funcion.espera>=20)&&(funcion.espera<=27)) escribir_palabra\ (71,38,"M",atributo); if ((funcion.espera>=28)&&(funcion.espera<=35)) escribir_palabra\ (72,38,"A",atributo); if ((funcion.espera>=36)&&(funcion.espera<=43)) escribir_palabra\ (73,38,"R",atributo); if ((funcion.espera>=44)&&(funcion.espera<=51)) escribir_palabra\ (74,38,"C",atributo); if ((funcion.espera>=52)&&(funcion.espera<=59)) escribir_palabra\ (75,38,"H",atributo); if ((funcion.espera>=60)&&(funcion.espera<=67)) escribir_palabra\ (76,38,"A",atributo); funcion.espera++; if (funcion.espera==68) funcion.espera=20; } eoi(); } /*-------------------------------------------VOID INTERRUPT TECLADO (__CPPARGS) Rutina de atencion a la interrupcion de teclado IRQ1. --------------------------------------------*/ void interrupt teclado(__CPPARGS){ 94 ITF51 u_int codigo; //Variable con el codigo pulsado codigo=inportb(0x60); if (SW1&0x01){ //Si la pausa esta activada: gestion_pausa(codigo); } else if (!(SW1&0x01)){ //Si la pausa esta desactivada: if (funcion.leer_car){ //Si la funcion leer caracter gestion_leer_car(codigo); //esta activada: } else if (funcion.leer_bin){ //Si la funcion leer valor gestion_leer_bin(codigo); //en binario esta activada: } else if (funcion.leer_dec){ //Si la funcion leer valor gestion_leer_dec(codigo); //en decimal esta activada: } else if (funcion.leer_hex){ //Si la funcion leer valor gestion_leer_hex(codigo); //en hexadecimal esta activada: } //Si no esta activada ninguna funcion de leer: else{ //Si pulsamos ESC y estamos en el menu principal del principio: if ((!(cursor.principal%10))&&(!cursor.conversor)&&(!cursor.color)\ &&(codigo==ESC)&&(!cursor.registros)&&(!cursor.memoria)\ &&(!cursor.pag_programa)&&(!cursor.pag_datos)&&(!cursor.pag_interna)\ &&(!fin)){ //Menu principal 10,20,30,40,50,60 + ESC fin++; fin_seguridad(); //Activamos el menu de fin de seguridad } else if ((!(cursor.principal%10))&&(fin==1)){//Finalizar: Si o No ? if ((codigo==ESC)||(codigo==N)){ //NO fin--; rectangulo (20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); } else if(codigo==S) fin++; //SI } else if ((cursor.principal)&&((cursor.principal<15)\ ||(cursor.principal>18))) menu_principal (codigo); else if ((cursor.principal>=15)&&(cursor.principal<=18))\ menu_ejecutar (codigo); else if (cursor.registros) menu_registros (codigo); else if (cursor.conversor) menu_conversor (codigo); 95 ITF51 else if (cursor.color) menu_color (codigo); else if ((cursor.memoria)&&(!cursor.pag_programa)&&(!cursor.pag_datos)\ &&(!cursor.pag_interna)) menu_memoria (codigo); else if (cursor.pag_programa) menu_mem_programa (codigo); else if (cursor.pag_datos) menu_mem_datos (codigo); else if (cursor.pag_interna) menu_mem_interna (codigo); } } eoi(); //Fin de interrupcion } /*-------------------------------------------VOID MENU_PRINCIPAL (CHAR CODIGO) Funcion que gestiona el codigo pulsado en el teclado dentro del menu principal. --------------------------------------------*/ void menu_principal (char codigo){ switch (cursor.principal) { case 10: /* Menu:PROGRAMA */ if (codigo==ABAJO){ escribir_palabra (2,12,"MEMORIA",atributo_inverso); escribir_palabra (2,5,"PROGRAMA",atributo); cursor.principal=20; } if ((codigo==DERECHA)||(codigo==ENTER)){ escribir_palabra (5,7,"Ejecutar",atributo_inverso); escribir_palabra (2,5,"PROGRAMA",atributo); cursor.principal=11; } break; case 11: /* Menu:PROGRAMA-Ejecutar */ if (codigo==ABAJO){ escribir_palabra (5,8,"Paso a Paso",atributo_inverso); escribir_palabra (5,7,"Ejecutar",atributo); cursor.principal=12; } if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,5,"PROGRAMA",atributo_inverso); escribir_palabra (5,7,"Ejecutar",atributo); cursor.principal=10; } if (codigo==ENTER){ 96 ITF51 if (SW1&0x04){ //programa transferido? if (SW1&0x02) opcion_main=9; //marcha? else{ escribir_palabra (2,2," M E N U ",atributo); escribir_palabra (5,7,"Ejecutar",atributo); cursor.principal=15; representar_ejecutar(1); } } else{ representar_error (12); SW1=SW1|0x01; //pausa activada } } break; case 12: /* Menu:PROGRAMA-Paso a Paso */ if (codigo==ABAJO){ escribir_palabra (5,9,"Resetear",atributo_inverso); escribir_palabra (5,8,"Paso a Paso",atributo); cursor.principal=13; } if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,5,"PROGRAMA",atributo_inverso); escribir_palabra (5,8,"Paso a Paso",atributo); cursor.principal=10; } if (codigo==ARRIBA){ escribir_palabra (5,7,"Ejecutar",atributo_inverso); escribir_palabra (5,8,"Paso a Paso",atributo); cursor.principal=11; } if (codigo==ENTER){ if (SW1&0x04){ //programa transferido? if (SW1&0x02) opcion_main=9; //marcha? else{ escribir_palabra (2,2," M E N U ",atributo); escribir_palabra (5,8,"Paso a Paso",atributo); cursor.principal=17; representar_ejecutar(3); } } else{ representar_error (12); 97 ITF51 SW1=SW1|0x01; //pausa activada } } break; case 13: /* Menu:PROGRAMA-Resetear*/ if (codigo==ABAJO){ escribir_palabra (5,10,"Listar",atributo_inverso); escribir_palabra (5,9,"Resetear",atributo); cursor.principal=14; } if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,5,"PROGRAMA",atributo_inverso); escribir_palabra (5,9,"Resetear",atributo); cursor.principal=10; } if (codigo==ARRIBA){ escribir_palabra (5,8,"Paso a Paso",atributo_inverso); escribir_palabra (5,9,"Resetear",atributo); cursor.principal=12; } if (codigo==ENTER){ escribir_palabra (2,2," M E N U ",atributo); escribir_palabra (5,9,"Resetear",atributo); opcion_main=9; } break; case 14: /* Menu:PROGRAMA-Listar*/ if (codigo==ARRIBA){ escribir_palabra (5,9,"Resetear",atributo_inverso); escribir_palabra (5,10,"Listar",atributo); cursor.principal=13; } if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,5,"PROGRAMA",atributo_inverso); escribir_palabra (5,10,"Listar",atributo); cursor.principal=10; } if (codigo==ENTER){ if (SW1&0x10){ //Si trabajando sin archivo funcion.dph=0; //Preparar para que liste funcion.dpl=0; //desde 0 rectangulo(20,40,60,47,3,atributo); //Limpiamos el cuadro secundario opcion_main=4; 98 ITF51 } else if (!(SW1&0x10)){ //Si trabajando con archivo rectangulo (20,40,60,47,3,atributo); //Limpiamos el cuadro secundario escribir_palabra (2,2," ",atributo); M E N U escribir_palabra (5,10,"Listar",atributo); escribir_palabra (32,40,"³ escribir_palabra ³",atributo); (33,40,"LISTAR PROGRAMA",atributo_inverso); escribir_palabra (32,41,"ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ",atributo); escribir_palabra (29,44,"Introducir la direccion",atributo); escribir_palabra (29,46,"de PC inicial:",atributo); funcion.leer_hex=1; funcion.x=45; funcion.y=46; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } break; case 20: /* Menu:MEMORIA */ if (codigo==ABAJO){ escribir_palabra (2,18,"REGISTROS",atributo_inverso); escribir_palabra (2,12,"MEMORIA",atributo); cursor.principal=30; } if (codigo==ARRIBA){ escribir_palabra (2,5,"PROGRAMA",atributo_inverso); escribir_palabra (2,12,"MEMORIA",atributo); cursor.principal=10; } if ((codigo==DERECHA)||(codigo==ENTER)){ escribir_palabra (5,14,"Modificar",atributo_inverso); escribir_palabra (2,12,"MEMORIA",atributo); cursor.principal=21; } break; case 21: /* Menu:MEMORIA-Modificar */ if (codigo==ABAJO){ escribir_palabra (5,15,"Transferir",atributo_inverso); escribir_palabra (5,14,"Modificar",atributo); cursor.principal=22; } if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,12,"MEMORIA",atributo_inverso); escribir_palabra (5,14,"Modificar",atributo); 99 ITF51 cursor.principal=20; } if (codigo==ENTER){ if (SW1&0x02) opcion_main=9; //marcha? else{ escribir_palabra (2,2," M E N U ",atributo); escribir_palabra (5,14,"Modificar",atributo); representar_menu_memoria (1); cursor.principal=0; cursor.memoria=10; } } break; case 22: /* Menu:MEMORIA-Transferir */ if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,12,"MEMORIA",atributo_inverso); escribir_palabra (5,15,"Transferir",atributo); cursor.principal=20; } if (codigo==ARRIBA){ escribir_palabra (5,14,"Modificar",atributo_inverso); escribir_palabra (5,15,"Transferir",atributo); cursor.principal=21; } if (codigo==ENTER){ if (SW1&0x02) opcion_main=9; //marcha? else{ escribir_palabra (2,2," M E N U ",atributo); escribir_palabra (5,15,"Transferir",atributo); if (SW1&0x10){ SW1=SW1|0x01; //pausa activada representar_error(6); } else if (!(SW1&0x10)){ rectangulo (20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo); escribir_palabra (5,15,"Transferir",atributo); escribir_palabra (29,40,"³ escribir_palabra ³",atributo); (30,40,"TRANSFERIR PROGRAMA",atributo_inverso); escribir_palabra (29,41,"ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ",atributo); escribir_palabra (29,44,"Introducir la direccion",atributo); escribir_palabra (29,46,"de PC inicial:",atributo); funcion.leer_hex=1; 100 ITF51 funcion.x=45; funcion.y=46; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } } break; case 30: /* Menu:REGISTROS */ if (codigo==ABAJO){ escribir_palabra (2,24,"PUNTO DE RUPTURA",atributo_inverso); escribir_palabra (2,18,"REGISTROS",atributo); cursor.principal=40; } if (codigo==ARRIBA){ escribir_palabra (2,12,"MEMORIA",atributo_inverso); escribir_palabra (2,18,"REGISTROS",atributo); cursor.principal=20; } if ((codigo==DERECHA)||(codigo==ENTER)){ escribir_palabra (5,20,"Modificar",atributo_inverso); escribir_palabra (2,18,"REGISTROS",atributo); cursor.principal=31; } break; case 31: /* Menu:REGISTROS-Modificar */ if (codigo==ABAJO){ escribir_palabra (5,21,"Listar",atributo_inverso); escribir_palabra (5,20,"Modificar",atributo); cursor.principal=32; } if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,18,"REGISTROS",atributo_inverso); escribir_palabra (5,20,"Modificar",atributo); cursor.principal=30; } if (codigo==ENTER){ if (SW1&0x02) opcion_main=9; //marcha? else{ escribir_palabra (63,5,"DPH",atributo_inverso); escribir_palabra (63,2," REGISTROS ",atributo_inverso); escribir_palabra (2,2," M E N U ",atributo); escribir_palabra (5,20,"Modificar",atributo); cursor.principal=0; 101 ITF51 cursor.registros=1; conversor(tabla_registros[1]); //Presentacion del valor convertido } } break; case 32: /* Menu:REGISTROS-Listar */ if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,18,"REGISTROS",atributo_inverso); escribir_palabra (5,21,"Listar",atributo); cursor.principal=30; } if (codigo==ARRIBA){ escribir_palabra (5,20,"Modificar",atributo_inverso); escribir_palabra (5,21,"Listar",atributo); cursor.principal=31; } if ((codigo==ENTER)){ if (SW1&0x02) opcion_main=8; escribir_palabra (2,2," M E N U ",atributo); escribir_palabra (5,21,"Listar",atributo); } break; case 40: /* Menu:PUNTO DE RUPTURA */ if (codigo==ABAJO){ escribir_palabra (2,29,"UTILIDADES",atributo_inverso); escribir_palabra (2,24,"PUNTO DE RUPTURA",atributo); cursor.principal=50; } if (codigo==ARRIBA){ escribir_palabra (2,18,"REGISTROS",atributo_inverso); escribir_palabra (2,24,"PUNTO DE RUPTURA",atributo); cursor.principal=30; } if ((codigo==DERECHA)||(codigo==ENTER)){ escribir_palabra (5,26,"Activar",atributo_inverso); escribir_palabra (2,24,"PUNTO DE RUPTURA",atributo); cursor.principal=41; } break; case 41: /* Menu:PUNTO DE RUPTURA-Activar */ if (codigo==ABAJO){ escribir_palabra (5,27,"Desactivar",atributo_inverso); escribir_palabra (5,26,"Activar",atributo); 102 ITF51 cursor.principal=42; } if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,24,"PUNTO DE RUPTURA",atributo_inverso); escribir_palabra (5,26,"Activar",atributo); cursor.principal=40; } if (codigo==ENTER){ if (SW1&0x02) opcion_main=9; //marcha? else{ escribir_palabra (2,2," M E N U ",atributo); escribir_palabra (5,26,"Activar",atributo); escribir_palabra (63,24,"PUNTO--RUPTURA",atributo_inverso); funcion.leer_hex=1; funcion.x=74; funcion.y=27; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } break; case 42: /* Menu:PUNTO DE RUPTURA-Desactivar */ if (codigo==ARRIBA){ escribir_palabra (5,26,"Activar",atributo_inverso); escribir_palabra (5,27,"Desactivar",atributo); cursor.principal=41; } if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,24,"PUNTO DE RUPTURA",atributo_inverso); escribir_palabra (5,27,"Desactivar",atributo); cursor.principal=40; } if (codigo==ENTER){ if (SW1&0x02) opcion_main=9; //marcha? else{ SW1=SW1&0xF7; //p_ruptura desactivado representar_punto_ruptura(); } } break; case 50: /* Menu:UTILIDADES */ if (codigo==ABAJO){ escribir_palabra (2,34,"SALIR",atributo_inverso); escribir_palabra (2,29,"UTILIDADES",atributo); 103 ITF51 cursor.principal=60; } if (codigo==ARRIBA){ escribir_palabra (2,24,"PUNTO DE RUPTURA",atributo_inverso); escribir_palabra (2,29,"UTILIDADES",atributo); cursor.principal=40; } if ((codigo==DERECHA)||(codigo==ENTER)){ escribir_palabra (5,31,"Conversor",atributo_inverso); escribir_palabra (2,29,"UTILIDADES",atributo); cursor.principal=51; } break; case 51: /* Menu:UTILIDADES-Conversor */ if (codigo==ABAJO){ escribir_palabra (5,32,"Color",atributo_inverso); escribir_palabra (5,31,"Conversor",atributo); cursor.principal=52; } if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,29,"UTILIDADES",atributo_inverso); escribir_palabra (5,31,"Conversor",atributo); cursor.principal=50; } if (codigo==ENTER){ escribir_palabra (2,2," M E N U ",atributo); escribir_palabra (5,31,"Conversor",atributo); representar_menu_conversor (1); cursor.principal=0; cursor.conversor=1; } break; case 52: /* Menu:UTILIDADES-Color */ if (codigo==ARRIBA){ escribir_palabra (5,31,"Conversor",atributo_inverso); escribir_palabra (5,32,"Color",atributo); cursor.principal=51; } if ((codigo==IZQUIERDA)||(codigo==ESC)){ escribir_palabra (2,29,"UTILIDADES",atributo_inverso); escribir_palabra (5,32,"Color",atributo); cursor.principal=50; } 104 ITF51 if (codigo==ENTER){ escribir_palabra (2,2," M E N U ",atributo); escribir_palabra (5,32,"Color",atributo); representar_color (1); cursor.principal=0; cursor.color=1; } break; case 60: /* Menu:SALIR */ if (codigo==ARRIBA){ escribir_palabra (2,29,"UTILIDADES",atributo_inverso); escribir_palabra (2,34,"SALIR",atributo); cursor.principal=50; } else if (codigo==ENTER){ fin++; fin_seguridad(); } break; } } /*-------------------------------------------VOID MENU_EJECUTAR (CHAR CODIGO) Funcion que gestiona el codigo pulsado en el teclado dentro del menu de ejecucion. --------------------------------------------*/ void menu_ejecutar (char codigo){ switch (cursor.principal){ case 15: /* Menu-ejecutar:ULTIMA */ if (codigo==DERECHA){ cursor.principal=16; representar_ejecutar(2); } if (codigo==ESC){ //Volver al menu principal rectangulo (20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,7,"Ejecutar",atributo_inverso); cursor.principal=11; } if (codigo==ENTER){ if (SW1&0x02) opcion_main=9; else{ 105 ITF51 funcion.dph=tabla_registros[22]; funcion.dpl=tabla_registros[23]; opcion_main=1; } } break; case 16: /* Menu-ejecutar:NUEVA */ if (codigo==IZQUIERDA){ cursor.principal=15; representar_ejecutar(1); } if (codigo==ESC){ //Volver al menu principal rectangulo (20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,7,"Ejecutar",atributo_inverso); cursor.principal=11; } if (codigo==ENTER){ if (SW1&0x02) opcion_main=9; else{ rectangulo (20,44,60,47,3,atributo); funcion.leer_hex=1; funcion.x=38; funcion.y=45; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } break; case 17: /* Menu-paso a paso:ULTIMA */ if (codigo==DERECHA){ cursor.principal=18; representar_ejecutar(4); } if (codigo==ESC){ //Volver al menu principal rectangulo (20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,8,"Paso a Paso",atributo_inverso); cursor.principal=12; } if (codigo==ENTER){ funcion.dph=tabla_registros[22]; funcion.dpl=tabla_registros[23]; opcion_main=1; 106 ITF51 } break; case 18: /* Menu-paso a paso:NUEVA */ if (codigo==IZQUIERDA){ cursor.principal=17; representar_ejecutar(3); } if (codigo==ESC){ //Volver al menu principal rectangulo (20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,8,"Paso a Paso",atributo_inverso); cursor.principal=12; } if (codigo==ENTER){ rectangulo (20,44,60,47,3,atributo); funcion.leer_hex=1; funcion.x=38; funcion.y=45; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } break; } } /*-------------------------------------------VOID MENU_REGISTROS (CHAR CODIGO) Funcion que gestiona el codigo pulsado en el teclado dentro del menu de registros. --------------------------------------------*/ void menu_registros (char codigo){ if (codigo==ESC){ //Volver al menu principal representar_registros_estatico(0); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,20,"Modificar",atributo_inverso); cursor.registros=0; cursor.principal=31; } else if (codigo!=ESC){ switch (cursor.registros){ //Preparamos en com.dl case 1: //la direccion que cada com.dl=0x83; //registro ocupa en la break; //memoria interna case 2: 107 ITF51 com.dl=0x82; break; case 3: com.dl=0xD0; break; case 4: com.dl=0xE0; break; case 5: com.dl=0xF0; break; case 6: com.dl=0x81; break; case 7: com.dl=0x80; break; case 8: com.dl=0x90; break; case 9: com.dl=0xA0; break; case 10: com.dl=0xB0; break; case 11: com.dl=0xB8; break; case 12: com.dl=0xA8; break; case 13: com.dl=0x89; break; case 14: com.dl=0x88; break; case 15: com.dl=0x8C; break; case 16: com.dl=0x8A; 108 ITF51 break; case 17: com.dl=0x8D; break; case 18: com.dl=0x8B; break; case 19: com.dl=0x98; break; case 20: com.dl=0x99; break; case 21: com.dl=0x87; break; case 22: com.dl=0xF8; break; case 23: com.dl=0xF9; break; case 24: com.dl=0x00; break; case 25: com.dl=0x01; break; case 26: com.dl=0x02; break; case 27: com.dl=0x03; break; case 28: com.dl=0x04; break; case 29: com.dl=0x05; break; case 30: com.dl=0x06; break; 109 ITF51 case 31: com.dl=0x07; break; } if (cursor.registros==1){ //Esquina sup-iz if (codigo==ABAJO){ representar_registros_estatico (2); cursor.registros=2; } else if (codigo==DERECHA){ representar_registros_estatico (17); cursor.registros=17; } else if (codigo==ENTER){ funcion.leer_hex=1; funcion.x=68; funcion.y=cursor.registros+4; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } conversor(tabla_registros[cursor.registros]); //Presentacion del valor convertido } else if ((cursor.registros>1)&&(cursor.registros<16)){ //Columna izquierda if (codigo==ABAJO){ cursor.registros=cursor.registros+1; } else if (codigo==ARRIBA){ cursor.registros--; } else if (codigo==DERECHA){ cursor.registros=cursor.registros+16; } else if (codigo==ENTER){ funcion.leer_hex=1; funcion.x=68; funcion.y=cursor.registros+4; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } representar_registros_estatico (cursor.registros); conversor(tabla_registros[cursor.registros]); //Presentacion del valor convertido } 110 ITF51 else if (cursor.registros==16){ //Esquina inf-iz if (codigo==ARRIBA){ cursor.registros=15; } else if (codigo==ENTER){ funcion.leer_hex=1; funcion.x=68; funcion.y=cursor.registros+4; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } representar_registros_estatico (cursor.registros); conversor(tabla_registros[cursor.registros]); //Presentacion del valor convertido } else if (cursor.registros==17){ //Esquina sup-der if (codigo==ABAJO){ representar_registros_estatico (18); cursor.registros=18; } else if (codigo==IZQUIERDA){ representar_registros_estatico (1); cursor.registros=1; } else if (codigo==ENTER){ funcion.leer_hex=1; funcion.x=76; funcion.y=cursor.registros-12; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } conversor(tabla_registros[cursor.registros]); //Presentacion del valor convertido } else if ((cursor.registros>17)&&(cursor.registros<31)){ //Columna derecha if (codigo==ABAJO){ cursor.registros++; } else if (codigo==ARRIBA){ cursor.registros--; } else if (codigo==IZQUIERDA){ cursor.registros=cursor.registros-16; } 111 ITF51 else if (codigo==ENTER){ funcion.leer_hex=1; funcion.x=76; funcion.y=cursor.registros-12; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } representar_registros_estatico (cursor.registros); conversor(tabla_registros[cursor.registros]); //Presentacion del valor convertido } else if (cursor.registros==31){ //Esquina inf-der if (codigo==ARRIBA){ cursor.registros=30; } else if (codigo==ENTER){ funcion.leer_hex=1; funcion.x=76; funcion.y=cursor.registros-12; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } else if (codigo==IZQUIERDA){ cursor.registros=15; } representar_registros_estatico (cursor.registros); conversor(tabla_registros[cursor.registros]); //Presentacion del valor convertido } } } /*-------------------------------------------VOID MENU_MEMORIA (CHAR CODIGO) Funcion que gestiona el codigo pulsado en el teclado dentro del menu de memoria. --------------------------------------------*/ void menu_memoria (char codigo){ if (codigo==ESC){ //Volver al menu principal rectangulo (20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,14,"Modificar",atributo_inverso); cursor.principal=21; cursor.memoria=0; } 112 ITF51 else if (codigo!=ESC){ if (cursor.memoria==10){ /* Menu-memoria:PROGRAMA */ if (codigo==DERECHA){ representar_menu_memoria (2); cursor.memoria++; } else if (codigo==ENTER){ //El cursor entra dentro de rectangulo (20,40,60,47,3,atributo); //la pagina que representa cursor.pag_programa=1; //la memoria de programa representar_memoria_estatico (1,1); representar_memoria_dinamico (1,1); } } else if (cursor.memoria==11){ /* Menu-memoria:DATOS */ if (codigo==DERECHA){ representar_menu_memoria (3); cursor.memoria++; } else if (codigo==IZQUIERDA){ representar_menu_memoria (1); cursor.memoria--; } else if (codigo==ENTER){ //El cursor entra dentro de rectangulo (20,40,60,47,3,atributo); //la pagina que representa cursor.pag_datos=1; //la memoria de datos representar_memoria_estatico (1,2); representar_memoria_dinamico (1,2); } } else if (cursor.memoria==12){ /* Menu-memoria:INTERNA */ if (codigo==IZQUIERDA){ representar_menu_memoria (2); cursor.memoria--; } else if (codigo==ENTER){ //El cursor entra dentro de rectangulo (20,40,60,47,3,atributo); //la pagina que representa //la memoria de datos //Actualizamos los valores de los registros en el archivo //que representa la memoria interna f_escribir_caracter (tabla_registros[1],mem_interna,0x83); f_escribir_caracter (tabla_registros[2],mem_interna,0x82); f_escribir_caracter (tabla_registros[3],mem_interna,0xD0); f_escribir_caracter (tabla_registros[4],mem_interna,0xE0); 113 ITF51 f_escribir_caracter (tabla_registros[5],mem_interna,0xF0); f_escribir_caracter (tabla_registros[6],mem_interna,0x81); f_escribir_caracter (tabla_registros[7],mem_interna,0x80); f_escribir_caracter (tabla_registros[8],mem_interna,0x90); f_escribir_caracter (tabla_registros[9],mem_interna,0xA0); f_escribir_caracter (tabla_registros[10],mem_interna,0xB0); f_escribir_caracter (tabla_registros[11],mem_interna,0xB8); f_escribir_caracter (tabla_registros[12],mem_interna,0xA8); f_escribir_caracter (tabla_registros[13],mem_interna,0x89); f_escribir_caracter (tabla_registros[14],mem_interna,0x88); f_escribir_caracter (tabla_registros[15],mem_interna,0x8C); f_escribir_caracter (tabla_registros[16],mem_interna,0x8A); f_escribir_caracter (tabla_registros[17],mem_interna,0x8D); f_escribir_caracter (tabla_registros[18],mem_interna,0x8B); f_escribir_caracter (tabla_registros[19],mem_interna,0x98); f_escribir_caracter (tabla_registros[20],mem_interna,0x99); f_escribir_caracter (tabla_registros[21],mem_interna,0x87); f_escribir_caracter (tabla_registros[22],mem_interna,0xF8); f_escribir_caracter (tabla_registros[23],mem_interna,0xF9); cursor.pag_interna=1; representar_memoria_estatico (1,3); representar_memoria_dinamico (1,3); } } } } /*-------------------------------------------VOID MENU_MEM_PROGRAMA (CHAR CODIGO) Funcion que gestiona el codigo pulsado en el teclado dentro de la memoria de programa. --------------------------------------------*/ void menu_mem_programa (char codigo){ int temp,central; //Variables de ayuda central=1; if (codigo==ESC){ //Salimos al menu de memoria representar_menu_memoria(1); cursor.pag_programa=0; cursor.mem_programa=0; representar_memoria_estatico(0,1); representar_memoria_dinamico(0,1); } 114 ITF51 else if (codigo!=ESC){ if (codigo==REPAG){ if (cursor.pag_programa>1){ //Si no estamos en la 1ra pagina cursor.pag_programa--; representar_memoria_estatico(1,1); } } else if (codigo==AVPAG){ if (cursor.pag_programa<32){ //Si no estamos en la ultima pag. cursor.pag_programa++; representar_memoria_estatico(1,1); } } else if ((codigo!=REPAG)&&(codigo!=AVPAG)){ if (cursor.mem_programa==0x00){ //Esquina sup.iz. central=0; if (codigo==ARRIBA){ if (cursor.pag_programa>1){ //Si no estamos en la 1ra pagina cursor.pag_programa--; cursor.mem_programa=cursor.mem_programa+0xF8; representar_memoria_estatico(1,1); } } else if (codigo==ABAJO) cursor.mem_programa=cursor.mem_programa+0x08; else if (codigo==DERECHA) cursor.mem_programa++; else if (codigo==ENTER){ temp=0; if ((cursor.mem_programa&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_programa&0x0007)*3; funcion.y=5+2*((cursor.mem_programa&0x00F0)>>1)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (cursor.mem_programa==0x07){ //Esquina sup.der. central=0; if (codigo==ARRIBA){ if (cursor.pag_programa>1){ //Si no estamos en la 1ra pagina cursor.pag_programa--; cursor.mem_programa=cursor.mem_programa+0xF8; representar_memoria_estatico(1,1); 115 ITF51 } } else if (codigo==ABAJO) cursor.mem_programa=cursor.mem_programa+0x08; else if (codigo==IZQUIERDA) cursor.mem_programa--; else if (codigo==ENTER){ temp=0; if ((cursor.mem_programa&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_programa&0x0007)*3; funcion.y=5+2*((cursor.mem_programa&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (cursor.mem_programa==0xF8){ //Esquina inf.iz. central=0; if (codigo==DERECHA) cursor.mem_programa++; else if (codigo==ARRIBA) cursor.mem_programa=cursor.mem_programa-0x08; else if (codigo==ABAJO){ if (cursor.pag_programa<32){ //Si no estamos en la ultima pag. cursor.pag_programa++; cursor.mem_programa=cursor.mem_programa-0xF8; representar_memoria_estatico(1,1); } } else if (codigo==ENTER){ temp=0; if ((cursor.mem_programa&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_programa&0x0007)*3; funcion.y=5+2*((cursor.mem_programa&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (cursor.mem_programa==0xFF){ //Esquina inf.der. central=0; if (codigo==IZQUIERDA) cursor.mem_programa--; else if (codigo==ARRIBA) cursor.mem_programa=cursor.mem_programa-0x08; else if (codigo==ABAJO){ if (cursor.pag_programa<32){ //Si no estamos en la ultima pag. 116 ITF51 cursor.pag_programa++; cursor.mem_programa=cursor.mem_programa-0xF8; representar_memoria_estatico(1,1); } } else if (codigo==ENTER){ temp=0; if ((cursor.mem_programa&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_programa&0x0007)*3; funcion.y=5+2*((cursor.mem_programa&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (((cursor.mem_programa&0x0F)==0x00)\ ||((cursor.mem_programa&0x0F)==0x08)){ //Columna izquierda central=0; if (codigo==ABAJO) cursor.mem_programa=cursor.mem_programa+0x08; else if (codigo==DERECHA) cursor.mem_programa++; else if (codigo==ARRIBA) cursor.mem_programa=cursor.mem_programa-0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_programa&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_programa&0x0007)*3; funcion.y=5+2*((cursor.mem_programa&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (((cursor.mem_programa&0x0F)==0x07)\ ||((cursor.mem_programa&0x0F)==0x0F)){ //Columna derecha central=0; if (codigo==ABAJO) cursor.mem_programa=cursor.mem_programa+0x08; else if (codigo==IZQUIERDA) cursor.mem_programa--; else if (codigo==ARRIBA) cursor.mem_programa=cursor.mem_programa-0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_programa&0x000F)>0x0007) temp++; //Situamos las variables 117 ITF51 //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_programa&0x0007)*3; funcion.y=5+2*((cursor.mem_programa&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (((cursor.mem_programa&0xF0)==0xF0)\ &&(cursor.mem_programa>0xF7)){ //Fila inferior central=0; if (codigo==IZQUIERDA) cursor.mem_programa--; else if (codigo==DERECHA) cursor.mem_programa++; else if (codigo==ARRIBA) cursor.mem_programa=cursor.mem_programa-0x08; else if (codigo==ABAJO){ if (cursor.pag_programa<32){ //Si no estamos en la ultima pag. cursor.pag_programa++; cursor.mem_programa=cursor.mem_programa-0xF8; representar_memoria_estatico(1,1); } } else if (codigo==ENTER){ temp=0; if ((cursor.mem_programa&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_programa&0x0007)*3; funcion.y=5+2*((cursor.mem_programa&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (((cursor.mem_programa&0xF0)==0x00)\ &&(cursor.mem_programa<0x08)){ //Fila superior central=0; if (codigo==IZQUIERDA) cursor.mem_programa--; else if (codigo==DERECHA) cursor.mem_programa++; else if (codigo==ARRIBA){ if (cursor.pag_programa>1){ //Si no estamos en la 1ra pagina cursor.pag_programa--; cursor.mem_programa=cursor.mem_programa+0xF8; representar_memoria_estatico(1,1); } } 118 ITF51 else if (codigo==ABAJO) cursor.mem_programa=cursor.mem_programa+0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_programa&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_programa&0x0007)*3; funcion.y=5+2*((cursor.mem_programa&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (central) { //Posiciones centrales if (codigo==IZQUIERDA) cursor.mem_programa--; else if (codigo==DERECHA) cursor.mem_programa++; else if (codigo==ARRIBA) cursor.mem_programa=cursor.mem_programa-0x08; else if (codigo==ABAJO) cursor.mem_programa=cursor.mem_programa+0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_programa&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_programa&0x0007)*3; funcion.y=5+2*((cursor.mem_programa&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } } //Enviamos el valor del byte //al conversor temp=(cursor.mem_programa+(cursor.pag_programa-1)*256); conversor (f_leer_caracter(mem_programa,temp)); //Presentacion del valor convertido if (!funcion.leer_hex) representar_memoria_dinamico(1,1); } } /*-------------------------------------------VOID MENU_MEM_DATOS (CHAR CODIGO) Funcion que gestiona el codigo pulsado en el teclado dentro de la memoria de datos. --------------------------------------------*/ 119 ITF51 void menu_mem_datos (char codigo){ int temp,central; //Variables de ayuda central=1; if (codigo==ESC){ //Salimos al menu de memoria representar_menu_memoria(1); cursor.pag_datos=0; cursor.mem_datos=0; cursor.memoria=10; representar_memoria_estatico(0,2); representar_memoria_dinamico(0,2); } else if (codigo!=ESC){ if (codigo==REPAG){ if (cursor.pag_datos>1){ //Si no estamos en la 1ra pagina cursor.pag_datos--; representar_memoria_estatico(1,2); } } else if (codigo==AVPAG){ if (cursor.pag_datos<192){ //Si no estamos en la ultima pag. cursor.pag_datos++; representar_memoria_estatico(1,2); } } else if ((codigo!=REPAG)&&(codigo!=AVPAG)){ if (cursor.mem_datos==0x00){ //Esquina sup.iz. central=0; if (codigo==ARRIBA){ if (cursor.pag_datos>1){ //Si no estamos en la 1ra pagina cursor.pag_datos--; cursor.mem_datos=cursor.mem_datos+0xF8; representar_memoria_estatico(1,2); } } else if (codigo==ABAJO) cursor.mem_datos=cursor.mem_datos+0x08; else if (codigo==DERECHA) cursor.mem_datos++; else if (codigo==ENTER){ temp=0; if ((cursor.mem_datos&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_datos&0x0007)*3; 120 ITF51 funcion.y=5+2*((cursor.mem_datos&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (cursor.mem_datos==0x07){ //Esquina sup.der. central=0; if (codigo==ARRIBA){ if (cursor.pag_datos>1){ //Si no estamos en la 1ra pagina cursor.pag_datos--; cursor.mem_datos=cursor.mem_datos+0xF8; representar_memoria_estatico(1,2); } } else if (codigo==ABAJO) cursor.mem_datos=cursor.mem_datos+0x08; else if (codigo==IZQUIERDA) cursor.mem_datos--; else if (codigo==ENTER){ temp=0; if ((cursor.mem_datos&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_datos&0x0007)*3; funcion.y=5+2*((cursor.mem_datos&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (cursor.mem_datos==0xF8){ //Esquina inf.iz. central=0; if (codigo==DERECHA) cursor.mem_datos++; else if (codigo==ARRIBA) cursor.mem_datos=cursor.mem_datos-0x08; else if (codigo==ABAJO){ if (cursor.pag_programa<192){ //Si no estamos en la ultima pag. cursor.pag_datos++; cursor.mem_datos=cursor.mem_datos-0xF8; representar_memoria_estatico(1,2); } } else if (codigo==ENTER){ temp=0; if ((cursor.mem_datos&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; 121 ITF51 funcion.x=26+(cursor.mem_datos&0x0007)*3; funcion.y=5+2*((cursor.mem_datos&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (cursor.mem_datos==0xFF){ //Esquina inf.der. central=0; if (codigo==IZQUIERDA) cursor.mem_datos--; else if (codigo==ARRIBA) cursor.mem_datos=cursor.mem_datos-0x08; else if (codigo==ABAJO){ if (cursor.pag_datos<192){ //Si no estamos en la ultima pag. cursor.pag_datos++; cursor.mem_datos=cursor.mem_datos-0xF8; representar_memoria_estatico(1,2); } } else if (codigo==ENTER){ temp=0; if ((cursor.mem_datos&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_datos&0x0007)*3; funcion.y=5+2*((cursor.mem_datos&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (((cursor.mem_datos&0x0F)==0x00)\ ||((cursor.mem_datos&0x0F)==0x08)){ //Columna izquierda central=0; if (codigo==ABAJO) cursor.mem_datos=cursor.mem_datos+0x08; else if (codigo==DERECHA) cursor.mem_datos++; else if (codigo==ARRIBA) cursor.mem_datos=cursor.mem_datos-0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_datos&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_datos&0x0007)*3; funcion.y=5+2*((cursor.mem_datos&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } 122 ITF51 } else if (((cursor.mem_datos&0x0F)==0x07)\ ||((cursor.mem_datos&0x0F)==0x0F)){ //Columna derecha central=0; if (codigo==ABAJO) cursor.mem_datos=cursor.mem_datos+0x08; else if (codigo==IZQUIERDA) cursor.mem_datos--; else if (codigo==ARRIBA) cursor.mem_datos=cursor.mem_datos-0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_datos&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_datos&0x0007)*3; funcion.y=5+2*((cursor.mem_datos&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (((cursor.mem_datos&0xF0)==0xF0)\ &&(cursor.mem_datos>0xF7)){ //Fila inferior central=0; if (codigo==IZQUIERDA) cursor.mem_datos--; else if (codigo==DERECHA) cursor.mem_datos++; else if (codigo==ARRIBA) cursor.mem_datos=cursor.mem_datos-0x08; else if (codigo==ABAJO){ if (cursor.pag_datos<192){ //Si no estamos en la ultima pag. cursor.pag_datos++; cursor.mem_datos=cursor.mem_datos-0xF8; representar_memoria_estatico(1,2); } } else if (codigo==ENTER){ temp=0; if ((cursor.mem_datos&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_datos&0x0007)*3; funcion.y=5+2*((cursor.mem_datos&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (((cursor.mem_datos&0xF0)==0x00)\ 123 ITF51 &&(cursor.mem_datos<0x08)){ //Fila superior central=0; if (codigo==IZQUIERDA) cursor.mem_datos--; else if (codigo==DERECHA) cursor.mem_datos++; else if (codigo==ARRIBA){ if (cursor.pag_datos>1){ //Si no estamos en la 1ra pagina cursor.pag_datos--; cursor.mem_datos=cursor.mem_datos+0xF8; representar_memoria_estatico(1,2); } } else if (codigo==ABAJO) cursor.mem_datos=cursor.mem_datos+0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_datos&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_datos&0x0007)*3; funcion.y=5+2*((cursor.mem_datos&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (central) { //Posiciones centrales if (codigo==IZQUIERDA) cursor.mem_datos--; else if (codigo==DERECHA) cursor.mem_datos++; else if (codigo==ARRIBA) cursor.mem_datos=cursor.mem_datos-0x08; else if (codigo==ABAJO) cursor.mem_datos=cursor.mem_datos+0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_datos&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_datos&0x0007)*3; funcion.y=5+2*((cursor.mem_datos&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } } //Enviamos el valor del byte //al conversor temp=(cursor.mem_datos+(cursor.pag_datos-1)*256); conversor (f_leer_caracter(mem_datos,temp)); 124 ITF51 //Presentacion del valor convertido if (!funcion.leer_hex) representar_memoria_dinamico(1,2); } } /*-------------------------------------------VOID MENU_MEM_INTERNA (CHAR CODIGO) Funcion que gestiona el codigo pulsado en el teclado dentro de la memoria interna. --------------------------------------------*/ void menu_mem_interna (char codigo){ int temp,central; //Variables de ayuda central=1; if (codigo==ESC){ //Salimos al menu de memoria representar_menu_memoria(1); cursor.pag_interna=0; cursor.mem_interna=0; cursor.memoria=10; representar_memoria_estatico(0,3); representar_memoria_dinamico(0,3); } else if (codigo!=ESC){ if (cursor.mem_interna==0x00){ //Esquina sup.iz. central=0; if (codigo==ABAJO) cursor.mem_interna=cursor.mem_interna+0x08; else if (codigo==DERECHA) cursor.mem_interna++; else if (codigo==ENTER){ temp=0; if ((cursor.mem_interna&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_interna&0x0007)*3; funcion.y=5+2*((cursor.mem_interna&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (cursor.mem_interna==0x07){ //Esquina sup.der. central=0; if (codigo==ABAJO) cursor.mem_interna=cursor.mem_interna+0x08; else if (codigo==IZQUIERDA) cursor.mem_interna--; else if (codigo==ENTER){ temp=0; 125 ITF51 if ((cursor.mem_interna&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_interna&0x0007)*3; funcion.y=5+2*((cursor.mem_interna&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (cursor.mem_interna==0xF8){ //Esquina inf.iz. central=0; if (codigo==DERECHA) cursor.mem_interna++; else if (codigo==ARRIBA) cursor.mem_interna=cursor.mem_interna-0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_interna&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_interna&0x0007)*3; funcion.y=5+2*((cursor.mem_interna&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (cursor.mem_interna==0xFF){ //Esquina inf.der. central=0; if (codigo==IZQUIERDA) cursor.mem_interna--; else if (codigo==ARRIBA) cursor.mem_interna=cursor.mem_interna-0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_interna&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_interna&0x0007)*3; funcion.y=5+2*((cursor.mem_interna&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (((cursor.mem_interna&0x0F)==0x00)\ ||((cursor.mem_interna&0x0F)==0x08)){ //Columna izquierda central=0; if (codigo==ABAJO) cursor.mem_interna=cursor.mem_interna+0x08; 126 ITF51 else if (codigo==DERECHA) cursor.mem_interna++; else if (codigo==ARRIBA) cursor.mem_interna=cursor.mem_interna-0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_interna&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_interna&0x0007)*3; funcion.y=5+2*((cursor.mem_interna&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (((cursor.mem_interna&0x0F)==0x07)\ ||((cursor.mem_interna&0x0F)==0x0F)){ //Columna derecha central=0; if (codigo==ABAJO) cursor.mem_interna=cursor.mem_interna+0x08; else if (codigo==IZQUIERDA) cursor.mem_interna--; else if (codigo==ARRIBA) cursor.mem_interna=cursor.mem_interna-0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_interna&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_interna&0x0007)*3; funcion.y=5+2*((cursor.mem_interna&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (((cursor.mem_interna&0xF0)==0xF0)\ &&(cursor.mem_interna>0xF7)){ //Fila inferior central=0; if (codigo==IZQUIERDA) cursor.mem_interna--; else if (codigo==DERECHA) cursor.mem_interna++; else if (codigo==ARRIBA) cursor.mem_interna=cursor.mem_interna-0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_interna&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_interna&0x0007)*3; 127 ITF51 funcion.y=5+2*((cursor.mem_interna&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (((cursor.mem_interna&0xF0)==0x00)\ &&(cursor.mem_interna<0x08)){ //Fila superior central=0; if (codigo==IZQUIERDA) cursor.mem_interna--; else if (codigo==DERECHA) cursor.mem_interna++; else if (codigo==ABAJO) cursor.mem_interna=cursor.mem_interna+0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_interna&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_interna&0x0007)*3; funcion.y=5+2*((cursor.mem_interna&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (central) { //Posiciones centrales if (codigo==IZQUIERDA) cursor.mem_interna--; else if (codigo==DERECHA) cursor.mem_interna++; else if (codigo==ARRIBA) cursor.mem_interna=cursor.mem_interna-0x08; else if (codigo==ABAJO) cursor.mem_interna=cursor.mem_interna+0x08; else if (codigo==ENTER){ temp=0; if ((cursor.mem_interna&0x000F)>0x0007) temp++; //Situamos las variables //funcion.x y funcion.y funcion.leer_hex=1; funcion.x=26+(cursor.mem_interna&0x0007)*3; funcion.y=5+2*((cursor.mem_interna&0x00F0)/16)+temp; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } //Enviamos el valor del byte //al conversor temp=(cursor.mem_interna+(cursor.pag_interna-1)*256); conversor (f_leer_caracter(mem_interna,temp)); //Presentacion del valor convertido if (!funcion.leer_hex) representar_memoria_dinamico(1,3); 128 ITF51 } } /*-------------------------------------------VOID MENU_CONVERSOR (CHAR CODIGO) Funcion que gestiona el codigo pulsado en el teclado dentro del menu de conversor. --------------------------------------------*/ void menu_conversor (char codigo){ if (codigo==ESC){ //Salimos al menu principal rectangulo (20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,31,"Conversor",atributo_inverso); cursor.conversor=0; cursor.principal=51; } else if (codigo!=ESC){ if (cursor.conversor==1){ /* Menu-conversor: DEC*/ if (codigo==DERECHA){ representar_menu_conversor (2); cursor.conversor=2; } else if (codigo==ENTER){ funcion.x=40; funcion.y=46; funcion.leer_dec=1; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } else if (cursor.conversor==2){ /* Menu-conversor: HEX*/ if (codigo==DERECHA){ representar_menu_conversor (3); cursor.conversor=3; } if (codigo==IZQUIERDA){ representar_menu_conversor (1); cursor.conversor=1; } else if (codigo==ENTER){ funcion.x=40; funcion.y=46; funcion.leer_hex=1; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); 129 ITF51 } } else if (cursor.conversor==3){ /* Menu-conversor: BIN*/ if (codigo==IZQUIERDA){ representar_menu_conversor (2); cursor.conversor=2; } else if (codigo==ENTER){ funcion.x=40; funcion.y=46; funcion.leer_bin=1; escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); } } } } /*-------------------------------------------VOID MENU_COLOR (CHAR CODIGO) Funcion que gestiona el codigo pulsado en el teclado dentro del menu de conversor. --------------------------------------------*/ void menu_color (char codigo){ if (codigo==ESC){ //Salimos al menu principal o //retrocedemos a la seleccion //del color del fondo if ((cursor.color>0)&&(cursor.color<9)){ //Si se estaba seleccionando //el FONDO rectangulo (20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,32,"Color",atributo_inverso); cursor.color=0; cursor.principal=52; } else if (cursor.color>8){ //Si se estaba seleccionando //el TEXTO representar_color(1); cursor.color=1; } } else if (codigo!=ESC){ if (cursor.color==1){ /* Menu-color: FONDO=Negro*/ 130 ITF51 if (codigo==DERECHA){ representar_color (5); cursor.color=5; } else if (codigo==ABAJO){ representar_color (2); cursor.color=2; } else if (codigo==ENTER){ escribir_palabra (26,43,"Negro",atributo); funcion.dpl=0x00; representar_color (9); cursor.color=9; } } else if (cursor.color==2){ /* Menu-color: FONDO=Azul*/ if (codigo==DERECHA){ representar_color (6); cursor.color=6; } else if (codigo==ABAJO){ representar_color (3); cursor.color=3; } else if (codigo==ARRIBA){ representar_color (1); cursor.color=1; } else if (codigo==ENTER){ escribir_palabra (26,43,"Azul",atributo); funcion.dpl=0x10; representar_color (9); cursor.color=9; } } else if (cursor.color==3){ /* Menu-color: FONDO=Verde*/ if (codigo==DERECHA){ representar_color (7); cursor.color=7; } else if (codigo==ABAJO){ representar_color (4); cursor.color=4; 131 ITF51 } else if (codigo==ARRIBA){ representar_color (2); cursor.color=2; } else if (codigo==ENTER){ escribir_palabra (26,43,"Verde",atributo); funcion.dpl=0x20; representar_color (9); cursor.color=9; } } else if (cursor.color==4){ /* Menu-color: FONDO=Cyan*/ if (codigo==DERECHA){ representar_color (8); cursor.color=8; } else if (codigo==ARRIBA){ representar_color (3); cursor.color=3; } else if (codigo==ENTER){ escribir_palabra (26,43,"Cyan",atributo); funcion.dpl=0x30; representar_color (9); cursor.color=9; } } else if (cursor.color==5){ /* Menu-color: FONDO=Rojo*/ if (codigo==IZQUIERDA){ representar_color (1); cursor.color=1; } else if (codigo==ABAJO){ representar_color (6); cursor.color=6; } else if (codigo==ENTER){ escribir_palabra (26,43,"Rojo",atributo); funcion.dpl=0x40; representar_color (9); cursor.color=9; } 132 ITF51 } else if (cursor.color==6){ /* Menu-color: FONDO=Magenta*/ if (codigo==IZQUIERDA){ representar_color (2); cursor.color=2; } else if (codigo==ABAJO){ representar_color (7); cursor.color=7; } else if (codigo==ARRIBA){ representar_color (5); cursor.color=5; } else if (codigo==ENTER){ escribir_palabra (26,43,"Magenta",atributo); funcion.dpl=0x50; representar_color (9); cursor.color=9; } } else if (cursor.color==7){ /* Menu-color: FONDO=Marron*/ if (codigo==IZQUIERDA){ representar_color (3); cursor.color=3; } else if (codigo==ABAJO){ representar_color (8); cursor.color=8; } else if (codigo==ARRIBA){ representar_color (6); cursor.color=6; } else if (codigo==ENTER){ escribir_palabra (26,43,"Marron",atributo); funcion.dpl=0x60; representar_color (9); cursor.color=9; } } else if (cursor.color==8){ /* Menu-color: FONDO=Gris claro*/ if (codigo==IZQUIERDA){ 133 ITF51 representar_color (4); cursor.color=4; } else if (codigo==ARRIBA){ representar_color (7); cursor.color=7; } else if (codigo==ENTER){ escribir_palabra (26,43,"Gris c.",atributo); funcion.dpl=0x70; representar_color (9); cursor.color=9; } } else if (cursor.color==9){ /* Menu-color: TEXTO=Negro*/ if (codigo==DERECHA){ representar_color (15); cursor.color=15; } else if (codigo==ABAJO){ representar_color (10); cursor.color=10; } else if (codigo==ENTER){ escribir_palabra (26,46,"Negro",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x00){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x00){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x00; funcion.dpl=funcion.dpl+0x00; SW1=SW1|0x01; //pausa activada cursor.color=23; 134 ITF51 } } } else if (cursor.color==10){ /* Menu-color: TEXTO=Azul*/ if (codigo==DERECHA){ representar_color (16); cursor.color=16; } else if (codigo==ABAJO){ representar_color (11); cursor.color=11; } else if (codigo==ARRIBA){ representar_color (9); cursor.color=9; } else if (codigo==ENTER){ escribir_palabra (26,46,"Azul",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x10){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x10){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x10; funcion.dpl=funcion.dpl+0x01; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } else if (cursor.color==11){ /* Menu-color: TEXTO=Verde*/ if (codigo==DERECHA){ representar_color (17); cursor.color=17; 135 ITF51 } else if (codigo==ABAJO){ representar_color (12); cursor.color=12; } else if (codigo==ARRIBA){ representar_color (10); cursor.color=10; } else if (codigo==ENTER){ escribir_palabra (26,46,"Verde",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x20){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x20){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x20; funcion.dpl=funcion.dpl+0x02; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } else if (cursor.color==12){ /* Menu-color: TEXTO=Cyan*/ if (codigo==DERECHA){ representar_color (18); cursor.color=18; } else if (codigo==ABAJO){ representar_color (13); cursor.color=13; } else if (codigo==ARRIBA){ representar_color (11); 136 ITF51 cursor.color=11; } else if (codigo==ENTER){ escribir_palabra (26,46,"Cyan",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x30){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x30){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x30; funcion.dpl=funcion.dpl+0x03; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } else if (cursor.color==13){ /* Menu-color: TEXTO=Rojo*/ if (codigo==DERECHA){ representar_color (19); cursor.color=19; } else if (codigo==ABAJO){ representar_color (14); cursor.color=14; } else if (codigo==ARRIBA){ representar_color (12); cursor.color=12; } else if (codigo==ENTER){ escribir_palabra (26,46,"Rojo",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x40){ escribir_palabra (36,43,"x Colores incompatibles",atributo); 137 ITF51 escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x40){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x40; funcion.dpl=funcion.dpl+0x04; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } else if (cursor.color==14){ /* Menu-color: TEXTO=Magenta*/ if (codigo==DERECHA){ representar_color (20); cursor.color=20; } else if (codigo==ARRIBA){ representar_color (13); cursor.color=13; } else if (codigo==ENTER){ escribir_palabra (26,46,"Magenta",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x50){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x50){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); 138 ITF51 funcion.dph=((funcion.dpl)>>4)+0x50; funcion.dpl=funcion.dpl+0x05; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } else if (cursor.color==15){ /* Menu-color: TEXTO=Marron*/ if (codigo==DERECHA){ representar_color (21); cursor.color=21; } if (codigo==IZQUIERDA){ representar_color (9); cursor.color=9; } else if (codigo==ABAJO){ representar_color (16); cursor.color=16; } else if (codigo==ENTER){ escribir_palabra (26,46,"Marron",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x60){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x60){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x60; funcion.dpl=funcion.dpl+0x06; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } 139 ITF51 else if (cursor.color==16){ /* Menu-color: TEXTO=Gris claro*/ if (codigo==DERECHA){ representar_color (22); cursor.color=22; } if (codigo==IZQUIERDA){ representar_color (10); cursor.color=10; } else if (codigo==ABAJO){ representar_color (17); cursor.color=17; } else if (codigo==ARRIBA){ representar_color (15); cursor.color=15; } else if (codigo==ENTER){ escribir_palabra (26,46,"Gris c.",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x70){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x70){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x70; funcion.dpl=funcion.dpl+0x07; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } else if (cursor.color==17){ /* Menu-color: TEXTO=Gris oscuro*/ if (codigo==IZQUIERDA){ representar_color (11); 140 ITF51 cursor.color=11; } else if (codigo==ABAJO){ representar_color (18); cursor.color=18; } else if (codigo==ARRIBA){ representar_color (16); cursor.color=16; } else if (codigo==ENTER){ escribir_palabra (26,46,"Gris o.",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x70){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x70){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x70; funcion.dpl=funcion.dpl+0x08; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } else if (cursor.color==18){ /* Menu-color: TEXTO=Azul claro*/ if (codigo==IZQUIERDA){ representar_color (12); cursor.color=12; } else if (codigo==ABAJO){ representar_color (19); cursor.color=19; } else if (codigo==ARRIBA){ 141 ITF51 representar_color (17); cursor.color=17; } else if (codigo==ENTER){ escribir_palabra (26,46,"Azul c.",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x10){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x10){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x10; funcion.dpl=funcion.dpl+0x09; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } else if (cursor.color==19){ /* Menu-color: TEXTO=Verde claro*/ if (codigo==IZQUIERDA){ representar_color (13); cursor.color=13; } else if (codigo==ABAJO){ representar_color (20); cursor.color=20; } else if (codigo==ARRIBA){ representar_color (18); cursor.color=18; } else if (codigo==ENTER){ escribir_palabra (26,46,"Verde c",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x20){ 142 ITF51 escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x20){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x20; funcion.dpl=funcion.dpl+0x0A; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } else if (cursor.color==20){ /* Menu-color: TEXTO=Cyan claro*/ if (codigo==IZQUIERDA){ representar_color (14); cursor.color=14; } else if (codigo==ARRIBA){ representar_color (19); cursor.color=19; } else if (codigo==ENTER){ escribir_palabra (26,46,"Cyan c.",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x30){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x30){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); 143 ITF51 escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x30; funcion.dpl=funcion.dpl+0x0B; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } else if (cursor.color==21){ /* Menu-color: TEXTO=Rojo claro*/ if (codigo==IZQUIERDA){ representar_color (15); cursor.color=15; } else if (codigo==ABAJO){ representar_color (22); cursor.color=22; } else if (codigo==ENTER){ escribir_palabra (26,46,"Rojo c.",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x40){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x40){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x40; funcion.dpl=funcion.dpl+0x0C; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } else if (cursor.color==22){ /* Menu-color: TEXTO=Magenta claro*/ if (codigo==IZQUIERDA){ representar_color (16); 144 ITF51 cursor.color=16; } else if (codigo==ARRIBA){ representar_color (21); cursor.color=21; } else if (codigo==ENTER){ escribir_palabra (26,46,"Mag c.",atributo); rectangulo (34,42,60,47,3,atributo); if (funcion.dpl==0x50){ escribir_palabra (36,43,"x Colores incompatibles",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); SW1=SW1|0x01; //pausa activada cursor.color=1; } else if (funcion.dpl!=0x50){ escribir_palabra (36,43,"V Colores aceptados",atributo); escribir_palabra (35,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (35,46,"Pulse ENTER para continuar",atributo); escribir_palabra (41,46,"ENTER",atributo|0x80); funcion.dph=((funcion.dpl)>>4)+0x50; funcion.dpl=funcion.dpl+0x0D; SW1=SW1|0x01; //pausa activada cursor.color=23; } } } } } /****************************************************** VOID GESTION_LEER_CAR (U_INT CODIGO); Dentro del servicio a la interrupcion del teclado gestiona las acciones que hacer para leer los caracteres del nombre del archivo. ******************************************************/ void gestion_leer_car (u_int codigo){ FILE *lst; u_int temp1; temp1=0; if ((codigo==ESC)&&(funcion.leer_car!=10)){ 145 ITF51 fin=2; funcion.leer_car=0; } else if (codigo!=ESC){ if (codigo==14){ //Borrar caracter if ((funcion.leer_car>1)&&(funcion.leer_car<9)){ ficheroTMP[funcion.leer_car-2]=0x00; funcion.leer_car--; escribir_palabra ((funcion.x+funcion.leer_car-1),funcion.y,"_\ ",(atributo_inverso|0x80)); } else if (funcion.leer_car==9){ ficheroTMP[funcion.leer_car-2]=0x00; escribir_palabra (funcion.x+7,funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_car--; } } else if (codigo==0x38) SW1=SW1|0x40; //altgr activado else if (codigo==0xB8) SW1=SW1&0xBF; //altgr desactivado else if ((codigo==0x2A)||(codigo==0x36)) SW1=SW1|0x80; //shift activado else if ((codigo==0xAA)||(codigo==0xB6)) SW1=SW1&0x7F; //shift desactivado // Seleccionamos aqui que boton del teclado ha sido pulsado: // El 1er if: SHIFT-off ALTGR-off // El 2do if: SHIFT-on ALTGR-off // El 3er if: SHIFT-off ALTGR-on else if (codigo==2){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=49; //"1" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=33; //"!" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==3){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=50; //"2" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dph=0; else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dpl=64; //"@" } else if (codigo==4){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=51; //"3" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=250; //"·" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dpl=35; //"#" 146 ITF51 } else if (codigo==5){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=52; //"4" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=36; //"$" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==6){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=53; //"5" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=37; //"%" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==7){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=54; //"6" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=38; //"&" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dpl=170; //"¬" } else if (codigo==8){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=55; //"7" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=47; //"/" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==9){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=56; //"8" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=40; //"(" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==10){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=57; //"9" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=41; //")" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==11){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=48; else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dph=0; else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } 147 //"0" ITF51 else if (codigo==12){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=39; //"'" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=63; //"?" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==13){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=173; //"-" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=168; //"¨" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==16){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=113; //"q" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=81; //"Q" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==17){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=119; //"w" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=87; //"W" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==18){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=101; //"e" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=69; //"E" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==19){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=114; //"r" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=82; //"R" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==20){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=116; //"t" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=84; //"T" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==21){ 148 ITF51 funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=121; //"y" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=89; //"Y" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==22){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=117; //"u" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=85; //"U" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==23){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=105; //"i" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=73; //"I" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==24){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=111; //"o" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=79; //"O" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==25){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=112; //"p" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=80; //"P" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==30){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=97; //"a" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=65; //"A" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==31){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=115; //"s" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=83; //"S" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==32){ funcion.dph=1; 149 ITF51 if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=100; //"d" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=68; //"D" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==33){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=102; //"f" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=70; //"F" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==34){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=103; //"g" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=71; //"G" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==35){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=104; //"h" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=72; //"H" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==36){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=106; //"j" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=74; //"J" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==37){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=107; //"k" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=75; //"K" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==38){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=108; //"l" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=76; //"L" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==39){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=164; 150 //"ñ" ITF51 else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=165; //"Ñ" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==43){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=135; //"ç" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=128; //"Ç" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==44){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=122; //"z" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=90; //"Z" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==45){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=120; //"x" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=88; //"X" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==46){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=99; //"c" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=67; //"C" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==47){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=118; //"v" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=86; //"V" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==48){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=98; //"b" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=66; //"B" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==49){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=110; //"n" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=78; //"N" 151 ITF51 else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==50){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=109; //"m" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=77; //"M" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if (codigo==53){ funcion.dph=1; if ((!(SW1&0x80))&&(!(SW1&0x40))) funcion.dpl=45; //"-" else if ((SW1&0x80)&&(!(SW1&0x40))) funcion.dpl=95; //"_" else if ((!(SW1&0x80))&&(SW1&0x40)) funcion.dph=0; } else if ((funcion.leer_car==1)&&(codigo==ENTER)){ SW1=SW1|0x10; //Si pulsamos ENTER sin ficheroLST[9]='n'; //escribir ningun carac- ficheroLST[10]='o'; //ter pasamos a trabajar ficheroLST[11]='f'; //sin fichero. Aqui se ficheroLST[12]='i'; //selecciona el fichero ficheroLST[13]='l'; //de listado "nofile.lst" ficheroLST[14]='e'; //, que contiene todo 00h ficheroLST[15]='.'; //, es decir: "NOP" ficheroLST[16]='L'; ficheroLST[17]='S'; ficheroLST[18]='T'; funcion.leer_car=0; } else if ((funcion.leer_car>1)&&(codigo==ENTER)&&(funcion.leer_car<10)){ //Tratamiento del nombre de la extension ".TSK" ficheroTMP[funcion.leer_car-1+9]=46; // "." ficheroTMP[funcion.leer_car+9]=84; // "T" ficheroTMP[funcion.leer_car+1+9]=83; // "S" ficheroTMP[funcion.leer_car+2+9]=75; // "K" for(temp1=0;temp1<funcion.leer_car+3;temp1++){ ficheroTSK[temp1+9]=ficheroTMP[temp1+9]; } for(temp1=(funcion.leer_car+3);temp1<11;temp1++){ ficheroTSK[temp1+9]=0; } //Tratamiento del nombre de la extension ".LST" ficheroTMP[funcion.leer_car-1+9]=46; // "." ficheroTMP[funcion.leer_car+9]=76; // "L" 152 ITF51 ficheroTMP[funcion.leer_car+1+9]=83; // "S" ficheroTMP[funcion.leer_car+2+9]=84; // "T" for(temp1=0;temp1<funcion.leer_car+3;temp1++){ ficheroLST[temp1+9]=ficheroTMP[temp1+9]; } for(temp1=(funcion.leer_car+3);temp1<11;temp1++){ ficheroLST[temp1+9]=0; } if (funcion.leer_car==8){ ficheroTSK[20]=0; ficheroLST[20]=0; } //Abrimos los 2 ficheros comprobando si existen. //Si no existe ficheroTSK entonces com.fichero=1; //Si no existe ficheroLST entonces com.fichero=2; if ((pro_original=fopen(ficheroTSK,"rb+"))==NULL){ com.fichero=1; escribir_palabra(28,39,ficheroTSK,atributo); } if ((lst=fopen(ficheroLST,"r"))==NULL){ com.fichero=2; escribir_palabra(28,41,ficheroLST,atributo); } fclose(lst); //Si hay error dibujamos el recuadro de error donde //se situan los nombres de archivos incorrectos if ((com.fichero==1)||(com.fichero==2)){ escribir_palabra(26,36,"Ú Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä ¿",atributo); escribir_palabra(26,37," ERROR: Imposible abrir ",atributo); escribir_palabra(26,38,"³ ³",atributo); escribir_palabra(26,40,"³ ³",atributo); escribir_palabra(26,42,"À Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ù",atributo); } //Arreglamos el atributo del ficheroTSK y entramos //en una pausa (funcion.leer_car=10) escribir_palabra(23,31," ",atributo); escribir_palabra(23,31,ficheroTSK,atributo); funcion.leer_car=10; escribir_palabra(22,45,"- Pulse una tecla para continuar -",atributo|0x80); } //Despues de la pausa: else if ((funcion.leer_car==10)&&(codigo<0x80)){ //Si hay error volvemos a empezar (funcion.leer_car=1) 153 ITF51 //la adquisicion del nombre del fichero. if ((com.fichero==1)||(com.fichero==2)){ com.fichero=0; funcion.leer_car=1; rectangulo (20,36,56,48,3,atributo); escribir_palabra(32,31,"_",atributo_inverso|0x80); escribir_palabra(33,31," ",atributo_inverso); escribir_palabra(40,31,".TSK",atributo); } //Si hay no hay error cerramos la funcion //con (funcion.leer_car=0) else if (!((com.fichero==1)||(com.fichero==2))){ funcion.leer_car=0; } } //Si no se ha pulsado ENTER seguimos pidiendo nuevos //caracteres resituandolos cada vez en su sitio if (funcion.dph){ if (funcion.leer_car<7){ ficheroTMP[funcion.leer_car-1+9]=funcion.dpl; escribir_car ((funcion.x+funcion.leer_car-\ 1),funcion.y,funcion.dpl,(atributo_inverso)); escribir_palabra ((funcion.x+funcion.leer_car),funcion.y,"_\ ",(atributo_inverso|0x80)); funcion.leer_car++; } else if (funcion.leer_car==7){ ficheroTMP[funcion.leer_car-1+9]=funcion.dpl; escribir_car ((funcion.x+funcion.leer_car-\ 1),funcion.y,funcion.dpl,(atributo_inverso)); escribir_palabra ((funcion.x+7),funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_car++; } else if (funcion.leer_car==8){ ficheroTMP[funcion.leer_car-1+9]=funcion.dpl; escribir_car ((funcion.x+funcion.leer_car\1),funcion.y,funcion.dpl,(atributo_inverso)); funcion.leer_car++; } funcion.dph=0; } } } 154 ITF51 /****************************************************** VOID GESTION_LEER_BIN (U_INT CODIGO); Dentro del servicio a la interrupcion del teclado gestiona las acciones que hacer para leer un valor binario de un byte de tama¤o. ******************************************************/ void gestion_leer_bin (u_int codigo){ u_char siguiente=0; funcion.dl=funcion.dpl; if (funcion.leer_bin==1){ funcion.dph=funcion.dpl=0; if (codigo==ESC){ //Desactivamos la funcion representar_menu_conversor (cursor.conversor); funcion.leer_bin=0; } else if (codigo!=ESC){ //Capturamos el bit7 if ((codigo==2)||(codigo==79)){ escribir_palabra (funcion.x,funcion.y,"1",atributo_inverso); funcion.dpl=funcion.dpl+128; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra (funcion.x,funcion.y,"0",atributo_inverso); siguiente=1; } if (siguiente){ escribir_palabra ((funcion.x)+1,funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_bin++; } } } else if (funcion.leer_bin==2){ if (codigo==ESC){ //Desactivamos la funcion representar_menu_conversor (cursor.conversor); funcion.leer_bin=0; } else if (codigo!=ESC){ //Capturamos el bit6 if (codigo==14){ //Borrar caracter escribir_palabra ((funcion.x),funcion.y,"_ ",(atributo_inverso|0x80)); funcion.dpl=0; funcion.leer_bin--; } else if (codigo!=14){ 155 ITF51 if ((codigo==2)||(codigo==79)){ escribir_palabra (funcion.x+1,funcion.y,"1",atributo_inverso); funcion.dpl=funcion.dpl+64; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra (funcion.x+1,funcion.y,"0",atributo_inverso); siguiente=1; } if (siguiente){ escribir_palabra ((funcion.x)+2,funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_bin++; } } } } else if (funcion.leer_bin==3){ if (codigo==ESC){ //Desactivamos la funcion if (cursor.conversor) representar_menu_conversor (cursor.conversor); funcion.leer_bin=0; } else if (codigo!=ESC){ //Capturamos el bit5 if (codigo==14){ //Borrar caracter escribir_palabra ((funcion.x)+1,funcion.y,"_ ",(atributo_inverso|0x80)); if (funcion.dl>=128) funcion.dl=funcion.dl-128; funcion.dpl=funcion.dpl-funcion.dl; funcion.leer_bin--; } else if (codigo!=14){ if ((codigo==2)||(codigo==79)){ escribir_palabra (funcion.x+2,funcion.y,"1",atributo_inverso); funcion.dpl=funcion.dpl+32; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra (funcion.x+2,funcion.y,"0",atributo_inverso); siguiente=1; } if (siguiente){ escribir_palabra ((funcion.x)+3,funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_bin++; } } 156 ITF51 } } else if (funcion.leer_bin==4){ if (codigo==ESC){ //Desactivamos la funcion if (cursor.conversor) representar_menu_conversor (cursor.conversor); funcion.leer_bin=0; } else if (codigo!=ESC){ //Capturamos el bit4 if (codigo==14){ //Borrar caracter escribir_palabra ((funcion.x)+2,funcion.y,"_ ",(atributo_inverso|0x80)); if (funcion.dl>=128) funcion.dl=funcion.dl-128; if (funcion.dl>=64) funcion.dl=funcion.dl-64; funcion.dpl=funcion.dpl-funcion.dl; funcion.leer_bin--; } else if (codigo!=14){ if ((codigo==2)||(codigo==79)){ escribir_palabra (funcion.x+3,funcion.y,"1",atributo_inverso); funcion.dpl=funcion.dpl+16; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra (funcion.x+3,funcion.y,"0",atributo_inverso); siguiente=1; } if (siguiente){ escribir_palabra ((funcion.x)+4,funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_bin++; } } } } else if (funcion.leer_bin==5){ if (codigo==ESC){ //Desactivamos la funcion if (cursor.conversor) representar_menu_conversor (cursor.conversor); funcion.leer_bin=0; } else if (codigo!=ESC){ //Capturamos el bit3 if (codigo==14){ //Borrar caracter escribir_palabra ((funcion.x)+3,funcion.y,"_ ",(atributo_inverso|0x80)); if (funcion.dl>=128) funcion.dl=funcion.dl-128; if (funcion.dl>=64) funcion.dl=funcion.dl-64; if (funcion.dl>=32) funcion.dl=funcion.dl-32; 157 ITF51 funcion.dpl=funcion.dpl-funcion.dl; funcion.leer_bin--; } else if (codigo!=14){ if ((codigo==2)||(codigo==79)){ escribir_palabra (funcion.x+4,funcion.y,"1",atributo_inverso); funcion.dpl=funcion.dpl+8; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra (funcion.x+4,funcion.y,"0",atributo_inverso); siguiente=1; } if (siguiente){ escribir_palabra ((funcion.x)+5,funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_bin++; } } } } else if (funcion.leer_bin==6){ if (codigo==ESC){ //Desactivamos la funcion if (cursor.conversor) representar_menu_conversor (cursor.conversor); funcion.leer_bin=0; } else if (codigo!=ESC){ //Capturamos el bit2 if (codigo==14){ //Borrar caracter escribir_palabra ((funcion.x)+4,funcion.y,"_ ",(atributo_inverso|0x80)); if (funcion.dl>=128) funcion.dl=funcion.dl-128; if (funcion.dl>=64) funcion.dl=funcion.dl-64; if (funcion.dl>=32) funcion.dl=funcion.dl-32; if (funcion.dl>=16) funcion.dl=funcion.dl-16; funcion.dpl=funcion.dpl-funcion.dl; funcion.leer_bin--; } else if (codigo!=14){ if ((codigo==2)||(codigo==79)){ escribir_palabra (funcion.x+5,funcion.y,"1",atributo_inverso); funcion.dpl=funcion.dpl+4; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra (funcion.x+5,funcion.y,"0",atributo_inverso); 158 ITF51 siguiente=1; } if (siguiente){ escribir_palabra ((funcion.x+6),funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_bin++; } } } } else if (funcion.leer_bin==7){ if (codigo==ESC){ //Desactivamos la funcion if (cursor.conversor) representar_menu_conversor (cursor.conversor); funcion.leer_bin=0; } else if (codigo!=ESC){ //Capturamos el bit1 if (codigo==14){ //Borrar caracter escribir_palabra ((funcion.x)+5,funcion.y,"_ ",(atributo_inverso|0x80)); if (funcion.dl>=128) funcion.dl=funcion.dl-128; if (funcion.dl>=64) funcion.dl=funcion.dl-64; if (funcion.dl>=32) funcion.dl=funcion.dl-32; if (funcion.dl>=16) funcion.dl=funcion.dl-16; if (funcion.dl>=8) funcion.dl=funcion.dl-8; funcion.dpl=funcion.dpl-funcion.dl; funcion.leer_bin--; } else if (codigo!=14){ if ((codigo==2)||(codigo==79)){ escribir_palabra (funcion.x+6,funcion.y,"1",atributo_inverso); funcion.dpl=funcion.dpl+2; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra (funcion.x+6,funcion.y,"0",atributo_inverso); siguiente=1; } if (siguiente){ escribir_palabra ((funcion.x)+7,funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_bin++; } } } } else if (funcion.leer_bin==8){ 159 ITF51 if (codigo==ESC){ //Desactivamos la funcion if (cursor.conversor) representar_menu_conversor (cursor.conversor); funcion.leer_bin=0; } else if (codigo!=ESC){ //Capturamos el bit0 if (codigo==14){ //Borrar caracter escribir_palabra ((funcion.x)+6,funcion.y,"_ ",(atributo_inverso|0x80)); if (funcion.dl>=128) funcion.dl=funcion.dl-128; if (funcion.dl>=64) funcion.dl=funcion.dl-64; if (funcion.dl>=32) funcion.dl=funcion.dl-32; if (funcion.dl>=16) funcion.dl=funcion.dl-16; if (funcion.dl>=8) funcion.dl=funcion.dl-8; if (funcion.dl>=4) funcion.dl=funcion.dl-4; funcion.dpl=funcion.dpl-funcion.dl; funcion.dpl=funcion.dpl-funcion.dph; funcion.leer_bin--; } else if (codigo!=14){ if ((codigo==2)||(codigo==79)){ escribir_palabra (funcion.x+7,funcion.y,"1",atributo_inverso); funcion.dpl=funcion.dpl+1; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra (funcion.x+7,funcion.y,"0",atributo_inverso); siguiente=1; } if (siguiente){ //Fin de introduccion del numero representar_menu_conversor (cursor.conversor); conversor(funcion.dpl); funcion.leer_bin=0; } } } } } /****************************************************** VOID GESTION_LEER_DEC (U_INT CODIGO); Dentro del servicio a la interrupcion del teclado gestiona las acciones que hacer para leer un valor decimal de 0 a 255. ******************************************************/ 160 ITF51 void gestion_leer_dec (u_int codigo){ u_char siguiente=0; if (funcion.leer_dec==1){ //Capturamos la 1ra cifra if (codigo==ESC){ //Cerramos la funcion if (cursor.conversor) representar_menu_conversor (cursor.conversor); funcion.leer_dec=0; } else if (codigo!=ESC){ //Adquisicion del valor if ((codigo==2)||(codigo==79)){ escribir_palabra (funcion.x,funcion.y,"1",atributo_inverso); funcion.dpl=100; siguiente=1; } else if ((codigo==3)||(codigo==80)){ escribir_palabra (funcion.x,funcion.y,"2",atributo_inverso); funcion.dpl=200; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra (funcion.x,funcion.y,"0",atributo_inverso); funcion.dpl=00; siguiente=1; } if (siguiente){ escribir_palabra ((funcion.x)+1,funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_dec++; } } } else if (funcion.leer_dec==2){ //Capturamos la 2da cifra if (codigo==ESC){ //Cerramos la funcion if (cursor.conversor) representar_menu_conversor (cursor.conversor); funcion.leer_dec=0; } else if (codigo!=ESC){ //Adquisicion del valor if (codigo==14){ //Borrar caracter escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); funcion.leer_dec--; } else if (codigo!=14){ if ((codigo==2)||(codigo==79)){ escribir_palabra ((funcion.x)+1,funcion.y,"1",atributo_inverso); funcion.dph=10; 161 ITF51 funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } else if ((codigo==3)||(codigo==80)){ escribir_palabra ((funcion.x)+1,funcion.y,"2",atributo_inverso); funcion.dph=20; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } else if ((codigo==4)||(codigo==81)){ escribir_palabra ((funcion.x)+1,funcion.y,"3",atributo_inverso); funcion.dph=30; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } else if ((codigo==5)||(codigo==75)){ escribir_palabra ((funcion.x)+1,funcion.y,"4",atributo_inverso); funcion.dph=40; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } else if ((codigo==6)||(codigo==76)){ escribir_palabra ((funcion.x)+1,funcion.y,"5",atributo_inverso); funcion.dph=50; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } else if ((codigo==7)||(codigo==77)){ escribir_palabra ((funcion.x)+1,funcion.y,"6",atributo_inverso); funcion.dph=60; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } else if ((codigo==8)||(codigo==71)){ escribir_palabra ((funcion.x)+1,funcion.y,"7",atributo_inverso); funcion.dph=70; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } else if ((codigo==9)||(codigo==72)){ escribir_palabra ((funcion.x)+1,funcion.y,"8",atributo_inverso); funcion.dph=80; funcion.dpl=funcion.dpl+funcion.dph; 162 ITF51 siguiente=1; } else if ((codigo==10)||(codigo==73)){ escribir_palabra ((funcion.x)+1,funcion.y,"9",atributo_inverso); funcion.dph=90; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra ((funcion.x)+1,funcion.y,"0",atributo_inverso); funcion.dph=00; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } if (siguiente){ escribir_palabra ((funcion.x)+2,funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_dec++; } } } } else if (funcion.leer_dec==3){ //Capturamos la 3ra cifra if (codigo==ESC){ //Cerramos la funcion if (cursor.conversor) representar_menu_conversor (cursor.conversor); funcion.leer_dec=0; } else if (codigo!=ESC){ //Adquisicion del valor if (codigo==14){ //Borrar caracter escribir_palabra ((funcion.x)+1,funcion.y,"_ ",(atributo_inverso|0x80)); funcion.leer_dec--; funcion.dpl=funcion.dpl-funcion.dph; } else if (codigo!=14){ if ((codigo==2)||(codigo==79)){ escribir_palabra ((funcion.x)+2,funcion.y,"1",atributo_inverso); funcion.dpl=(funcion.dpl)+1; siguiente=1; } else if ((codigo==3)||(codigo==80)){ escribir_palabra ((funcion.x)+2,funcion.y,"2",atributo_inverso); funcion.dpl=(funcion.dpl)+2; siguiente=1; } 163 ITF51 else if ((codigo==4)||(codigo==81)){ escribir_palabra ((funcion.x)+2,funcion.y,"3",atributo_inverso); funcion.dpl=(funcion.dpl)+3; siguiente=1; } else if ((codigo==5)||(codigo==75)){ escribir_palabra ((funcion.x)+2,funcion.y,"4",atributo_inverso); funcion.dpl=(funcion.dpl)+4; siguiente=1; } else if ((codigo==6)||(codigo==76)){ escribir_palabra ((funcion.x)+2,funcion.y,"5",atributo_inverso); funcion.dpl=(funcion.dpl)+5; siguiente=1; } if (funcion.dpl<250){ if ((codigo==7)||(codigo==77)){ escribir_palabra ((funcion.x)+1,funcion.y,"6",atributo_inverso); funcion.dph=6; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } else if ((codigo==8)||(codigo==71)){ escribir_palabra ((funcion.x)+1,funcion.y,"7",atributo_inverso); funcion.dph=7; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } else if ((codigo==9)||(codigo==72)){ escribir_palabra ((funcion.x)+1,funcion.y,"8",atributo_inverso); funcion.dph=8; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } else if ((codigo==10)||(codigo==73)){ escribir_palabra ((funcion.x)+1,funcion.y,"9",atributo_inverso); funcion.dph=9; funcion.dpl=funcion.dpl+funcion.dph; siguiente=1; } } if ((codigo==11)||(codigo==82)){ escribir_palabra ((funcion.x)+2,funcion.y,"0",atributo_inverso); 164 ITF51 funcion.dpl=(funcion.dpl)+0; siguiente=1; } if (siguiente){ //Fin de la funcion representar_menu_conversor (cursor.conversor); conversor(funcion.dpl); funcion.leer_dec=0; } } } } } /****************************************************** VOID GESTION_LEER_HEX (U_INT CODIGO); Dentro del servicio a la interrupcion del teclado gestiona las acciones que hacer para leer un valor hexadecimal de 0 a FF. ******************************************************/ void gestion_leer_hex (u_int codigo){ u_int temp1; u_char siguiente=0; if (funcion.leer_hex==1){ if (codigo==ESC){ if (cursor.registros) representar_registros_dinamico (0); else if (cursor.principal==41){ representar_punto_ruptura(); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,26,"Activar",atributo_inverso); } else if (cursor.principal==14){ rectangulo(20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,10,"Listar",atributo_inverso); } else if (cursor.principal==22){ rectangulo(20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,15,"Transferir",atributo_inverso); } else if (cursor.principal==16) representar_ejecutar (2); else if (cursor.principal==18) representar_ejecutar (4); else if (cursor.memoria==20) representar_menu_memoria (1); 165 ITF51 else if (cursor.memoria==21) representar_menu_memoria (2); else if (cursor.pag_programa) representar_memoria_dinamico (1,1); else if (cursor.pag_datos) representar_memoria_dinamico (1,2); else if (cursor.pag_interna) representar_memoria_dinamico (1,3); else if (cursor.conversor) representar_menu_conversor (cursor.conversor); funcion.leer_hex=0; } else if (codigo!=ESC){ if ((codigo==2)||(codigo==79)){ escribir_palabra (funcion.x,funcion.y,"1",atributo_inverso); funcion.dpl=0x10; siguiente=1; } else if ((codigo==3)||(codigo==80)){ escribir_palabra (funcion.x,funcion.y,"2",atributo_inverso); funcion.dpl=0x20; siguiente=1; } else if ((codigo==4)||(codigo==81)){ escribir_palabra (funcion.x,funcion.y,"3",atributo_inverso); funcion.dpl=0x30; siguiente=1; } else if ((codigo==5)||(codigo==75)){ escribir_palabra (funcion.x,funcion.y,"4",atributo_inverso); funcion.dpl=0x40; siguiente=1; } else if ((codigo==6)||(codigo==76)){ escribir_palabra (funcion.x,funcion.y,"5",atributo_inverso); funcion.dpl=0x50; siguiente=1; } else if ((codigo==7)||(codigo==77)){ escribir_palabra (funcion.x,funcion.y,"6",atributo_inverso); funcion.dpl=0x60; siguiente=1; } else if ((codigo==8)||(codigo==71)){ escribir_palabra (funcion.x,funcion.y,"7",atributo_inverso); funcion.dpl=0x70; siguiente=1; } 166 ITF51 else if ((codigo==9)||(codigo==72)){ escribir_palabra (funcion.x,funcion.y,"8",atributo_inverso); funcion.dpl=0x80; siguiente=1; } else if ((codigo==10)||(codigo==73)){ escribir_palabra (funcion.x,funcion.y,"9",atributo_inverso); funcion.dpl=0x90; siguiente=1; } else if ((codigo==11)||(codigo==79)){ escribir_palabra (funcion.x,funcion.y,"0",atributo_inverso); funcion.dpl=0x00; siguiente=1; } else if (codigo==30){ escribir_palabra (funcion.x,funcion.y,"A",atributo_inverso); funcion.dpl=0xA0; siguiente=1; } else if (codigo==48){ escribir_palabra (funcion.x,funcion.y,"B",atributo_inverso); funcion.dpl=0xB0; siguiente=1; } else if (codigo==46){ escribir_palabra (funcion.x,funcion.y,"C",atributo_inverso); funcion.dpl=0xC0; siguiente=1; } else if (codigo==32){ escribir_palabra (funcion.x,funcion.y,"D",atributo_inverso); funcion.dpl=0xD0; siguiente=1; } else if (codigo==18){ escribir_palabra (funcion.x,funcion.y,"E",atributo_inverso); funcion.dpl=0xE0; siguiente=1; } else if (codigo==33){ escribir_palabra (funcion.x,funcion.y,"F",atributo_inverso); funcion.dpl=0xF0; 167 ITF51 siguiente=1; } if (siguiente){ escribir_palabra ((funcion.x)+1,funcion.y,"_",(atributo_inverso|0x80)); funcion.leer_hex++; } } } else if (funcion.leer_hex==2){ if (codigo==ESC){ if (cursor.registros) representar_registros_dinamico (0); else if (cursor.principal==41){ representar_punto_ruptura(); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,26,"Activar",atributo_inverso); } else if (cursor.principal==14){ rectangulo(20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,10,"Listar",atributo_inverso); } else if (cursor.principal==22){ rectangulo(20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,15,"Transferir",atributo_inverso); } else if (cursor.principal==16) representar_ejecutar (2); else if (cursor.principal==18) representar_ejecutar (4); else if (cursor.memoria==20) representar_menu_memoria (1); else if (cursor.memoria==21) representar_menu_memoria (2); else if (cursor.pag_programa) representar_memoria_dinamico (1,1); else if (cursor.pag_datos) representar_memoria_dinamico (1,2); else if (cursor.pag_interna) representar_memoria_dinamico (1,3); else if (cursor.conversor) representar_menu_conversor (cursor.conversor); funcion.leer_hex=0; } else if (codigo!=ESC){ if (codigo==14){ //Borrar caracter escribir_palabra (funcion.x,funcion.y,"_ ",(atributo_inverso|0x80)); funcion.leer_hex--; } else if (codigo!=14){ if ((codigo==2)||(codigo==79)){ 168 ITF51 escribir_palabra ((funcion.x)+1,funcion.y,"1",atributo_inverso); funcion.dpl=(funcion.dpl)+0x01; siguiente=1; } else if ((codigo==3)||(codigo==80)){ escribir_palabra ((funcion.x)+1,funcion.y,"2",atributo_inverso); funcion.dpl=(funcion.dpl)+0x02; siguiente=1; } else if ((codigo==4)||(codigo==81)){ escribir_palabra ((funcion.x)+1,funcion.y,"3",atributo_inverso); funcion.dpl=(funcion.dpl)+0x03; siguiente=1; } else if ((codigo==5)||(codigo==75)){ escribir_palabra ((funcion.x)+1,funcion.y,"4",atributo_inverso); funcion.dpl=(funcion.dpl)+0x04; siguiente=1; } else if ((codigo==6)||(codigo==76)){ escribir_palabra ((funcion.x)+1,funcion.y,"5",atributo_inverso); funcion.dpl=(funcion.dpl)+0x05; siguiente=1; } else if ((codigo==7)||(codigo==77)){ escribir_palabra ((funcion.x)+1,funcion.y,"6",atributo_inverso); funcion.dpl=(funcion.dpl)+0x06; siguiente=1; } else if ((codigo==8)||(codigo==71)){ escribir_palabra ((funcion.x)+1,funcion.y,"7",atributo_inverso); funcion.dpl=(funcion.dpl)+0x07; siguiente=1; } else if ((codigo==9)||(codigo==72)){ escribir_palabra ((funcion.x)+1,funcion.y,"8",atributo_inverso); funcion.dpl=(funcion.dpl)+0x08; siguiente=1; } else if ((codigo==10)||(codigo==73)){ escribir_palabra ((funcion.x)+1,funcion.y,"9",atributo_inverso); funcion.dpl=(funcion.dpl)+0x09; siguiente=1; 169 ITF51 } else if ((codigo==11)||(codigo==82)){ escribir_palabra ((funcion.x)+1,funcion.y,"0",atributo_inverso); funcion.dpl=(funcion.dpl)+0x00; siguiente=1; } else if (codigo==30){ escribir_palabra ((funcion.x)+1,funcion.y,"A",atributo_inverso); funcion.dpl=(funcion.dpl)+0x0A; siguiente=1; } else if (codigo==48){ escribir_palabra ((funcion.x)+1,funcion.y,"B",atributo_inverso); funcion.dpl=(funcion.dpl)+0x0B; siguiente=1; } else if (codigo==46){ escribir_palabra ((funcion.x)+1,funcion.y,"C",atributo_inverso); funcion.dpl=(funcion.dpl)+0x0C; siguiente=1; } else if (codigo==32){ escribir_palabra ((funcion.x)+1,funcion.y,"D",atributo_inverso); funcion.dpl=(funcion.dpl)+0x0D; siguiente=1; } else if (codigo==18){ escribir_palabra ((funcion.x)+1,funcion.y,"E",atributo_inverso); funcion.dpl=(funcion.dpl)+0x0E; siguiente=1; } else if (codigo==33){ escribir_palabra ((funcion.x)+1,funcion.y,"F",atributo_inverso); funcion.dpl=(funcion.dpl)+0x0F; siguiente=1; } if (siguiente){ if (cursor.pag_programa||cursor.pag_datos||cursor.pag_interna){ funcion.leer_hex=0; opcion_main=1; } if (cursor.registros){ funcion.leer_hex=0; 170 ITF51 opcion_main=1; } if (cursor.conversor){ representar_menu_conversor (cursor.conversor); conversor (funcion.dpl); funcion.leer_hex=0; } if\ ((cursor.principal==41)||(cursor.principal==14)||(cursor.principal==22)||(cursor\ .principal==16)||(cursor.principal==18)){ escribir_palabra ((funcion.x)+2,funcion.y,"_",(atributo_inverso|0x80)); funcion.dph=funcion.dpl; funcion.leer_hex++; } } } } } else if (funcion.leer_hex==3){ if (codigo==ESC){ if (cursor.principal==41){ representar_punto_ruptura(); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,26,"Activar",atributo_inverso); } else if (cursor.principal==14){ rectangulo(20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,10,"Listar",atributo_inverso); } else if (cursor.principal==22){ rectangulo(20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,15,"Transferir",atributo_inverso); } else if (cursor.principal==16) representar_ejecutar (2); else if (cursor.principal==18) representar_ejecutar (4); else if (cursor.memoria==20) representar_menu_memoria (1); else if (cursor.memoria==21) representar_menu_memoria (2); funcion.leer_hex=0; } else if (codigo!=ESC){ if (codigo==14){ //Borrar caracter escribir_palabra ((funcion.x)+1,funcion.y,"_ ",(atributo_inverso|0x80)); 171 ITF51 funcion.dpl=((funcion.dph)&0x00F0); funcion.leer_hex--; } else if (codigo!=14){ if ((codigo==2)||(codigo==79)){ escribir_palabra ((funcion.x)+2,funcion.y,"1",atributo_inverso); funcion.dpl=0x10; siguiente=1; } else if ((codigo==3)||(codigo==80)){ escribir_palabra ((funcion.x)+2,funcion.y,"2",atributo_inverso); funcion.dpl=0x20; siguiente=1; } else if ((codigo==4)||(codigo==81)){ escribir_palabra ((funcion.x)+2,funcion.y,"3",atributo_inverso); funcion.dpl=0x30; siguiente=1; } else if ((codigo==5)||(codigo==75)){ escribir_palabra ((funcion.x)+2,funcion.y,"4",atributo_inverso); funcion.dpl=0x40; siguiente=1; } else if ((codigo==6)||(codigo==76)){ escribir_palabra ((funcion.x)+2,funcion.y,"5",atributo_inverso); funcion.dpl=0x50; siguiente=1; } else if ((codigo==7)||(codigo==77)){ escribir_palabra ((funcion.x)+2,funcion.y,"6",atributo_inverso); funcion.dpl=0x60; siguiente=1; } else if ((codigo==8)||(codigo==71)){ escribir_palabra ((funcion.x)+2,funcion.y,"7",atributo_inverso); funcion.dpl=0x70; siguiente=1; } else if ((codigo==9)||(codigo==72)){ escribir_palabra ((funcion.x)+2,funcion.y,"8",atributo_inverso); funcion.dpl=0x80; siguiente=1; 172 ITF51 } else if ((codigo==10)||(codigo==73)){ escribir_palabra ((funcion.x)+2,funcion.y,"9",atributo_inverso); funcion.dpl=0x90; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra ((funcion.x)+2,funcion.y,"0",atributo_inverso); funcion.dpl=0x00; siguiente=1; } else if (codigo==30){ escribir_palabra ((funcion.x)+2,funcion.y,"A",atributo_inverso); funcion.dpl=0xA0; siguiente=1; } else if (codigo==48){ escribir_palabra ((funcion.x)+2,funcion.y,"B",atributo_inverso); funcion.dpl=0xB0; siguiente=1; } else if (codigo==46){ escribir_palabra ((funcion.x)+2,funcion.y,"C",atributo_inverso); funcion.dpl=0xC0; siguiente=1; } else if (codigo==32){ escribir_palabra ((funcion.x)+2,funcion.y,"D",atributo_inverso); funcion.dpl=0xD0; siguiente=1; } else if (codigo==18){ escribir_palabra ((funcion.x)+2,funcion.y,"E",atributo_inverso); funcion.dpl=0xE0; siguiente=1; } else if (codigo==33){ escribir_palabra ((funcion.x)+2,funcion.y,"F",atributo_inverso); funcion.dpl=0xF0; siguiente=1; } if (siguiente){ escribir_palabra ((funcion.x)+3,funcion.y,"_",(atributo_inverso|0x80)); 173 ITF51 funcion.leer_hex++; } } } } else if (funcion.leer_hex==4){ if (codigo==ESC){ if (cursor.principal==41){ representar_punto_ruptura(); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,26,"Activar",atributo_inverso); } else if (cursor.principal==14){ rectangulo(20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,10,"Listar",atributo_inverso); } else if (cursor.principal==22){ rectangulo(20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,15,"Transferir",atributo_inverso); } else if (cursor.principal==16) representar_ejecutar (2); else if (cursor.principal==18) representar_ejecutar (4); else if (cursor.memoria==20) representar_menu_memoria (1); else if (cursor.memoria==21) representar_menu_memoria (2); funcion.leer_hex=0; } else if (codigo!=ESC){ if (codigo==14){ //Borrar caracter escribir_palabra ((funcion.x)+2,funcion.y,"_ ",(atributo_inverso|0x80)); funcion.leer_hex--; } else if (codigo!=14){ if ((codigo==2)||(codigo==79)){ escribir_palabra ((funcion.x)+2,funcion.y,"1",atributo_inverso); funcion.dpl=(funcion.dpl)+0x01; siguiente=1; } else if ((codigo==3)||(codigo==80)){ escribir_palabra ((funcion.x)+2,funcion.y,"2",atributo_inverso); funcion.dpl=(funcion.dpl)+0x02; siguiente=1; 174 ITF51 } else if ((codigo==4)||(codigo==81)){ escribir_palabra ((funcion.x)+2,funcion.y,"3",atributo_inverso); funcion.dpl=(funcion.dpl)+0x03; siguiente=1; } else if ((codigo==5)||(codigo==75)){ escribir_palabra ((funcion.x)+2,funcion.y,"4",atributo_inverso); funcion.dpl=(funcion.dpl)+0x04; siguiente=1; } else if ((codigo==6)||(codigo==76)){ escribir_palabra ((funcion.x)+2,funcion.y,"5",atributo_inverso); funcion.dpl=(funcion.dpl)+0x05; siguiente=1; } else if ((codigo==7)||(codigo==77)){ escribir_palabra ((funcion.x)+2,funcion.y,"6",atributo_inverso); funcion.dpl=(funcion.dpl)+0x06; siguiente=1; } else if ((codigo==8)||(codigo==71)){ escribir_palabra ((funcion.x)+2,funcion.y,"7",atributo_inverso); funcion.dpl=(funcion.dpl)+0x07; siguiente=1; } else if ((codigo==9)||(codigo==72)){ escribir_palabra ((funcion.x)+2,funcion.y,"8",atributo_inverso); funcion.dpl=(funcion.dpl)+0x08; siguiente=1; } else if ((codigo==10)||(codigo==73)){ escribir_palabra ((funcion.x)+2,funcion.y,"9",atributo_inverso); funcion.dpl=(funcion.dpl)+0x09; siguiente=1; } else if ((codigo==11)||(codigo==82)){ escribir_palabra ((funcion.x)+2,funcion.y,"0",atributo_inverso); funcion.dpl=(funcion.dpl)+0x00; siguiente=1; } else if (codigo==30){ escribir_palabra ((funcion.x)+2,funcion.y,"A",atributo_inverso); 175 ITF51 funcion.dpl=(funcion.dpl)+0x0A; siguiente=1; } else if (codigo==48){ escribir_palabra ((funcion.x)+2,funcion.y,"B",atributo_inverso); funcion.dpl=(funcion.dpl)+0x0B; siguiente=1; } else if (codigo==46){ escribir_palabra ((funcion.x)+2,funcion.y,"C",atributo_inverso); funcion.dpl=(funcion.dpl)+0x0C; siguiente=1; } else if (codigo==32){ escribir_palabra ((funcion.x)+2,funcion.y,"D",atributo_inverso); funcion.dpl=(funcion.dpl)+0x0D; siguiente=1; } else if (codigo==18){ escribir_palabra ((funcion.x)+2,funcion.y,"E",atributo_inverso); funcion.dpl=(funcion.dpl)+0x0E; siguiente=1; } else if (codigo==33){ escribir_palabra ((funcion.x)+2,funcion.y,"F",atributo_inverso); funcion.dpl=(funcion.dpl)+0x0F; siguiente=1; } if (siguiente){ if (cursor.principal==41){ temp1=(funcion.dph<<8)+funcion.dpl; if (temp1>0x1FFF){ SW1=SW1&0xF7; //p.ruptura desactivado representar_punto_ruptura(); representar_error(7); SW1=SW1|0x01; //pausa activada } else if (temp1<=0x1FFF){ p_ruptura.dph=funcion.dph; p_ruptura.dpl=funcion.dpl; SW1=SW1|0x08; //p_ruptura activado representar_punto_ruptura(); representar_ok(3); 176 ITF51 SW1=SW1|0x01; //pausa activada } } else if (cursor.principal==14){ rectangulo(20,40,60,47,3,atributo); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,10,"Listar",atributo_inverso); opcion_main=4; } else if (cursor.principal==22){ rectangulo(20,40,60,47,3,atributo); opcion_main=3; } else if ((cursor.principal==16)||(cursor.principal==18)){ rectangulo(20,40,60,47,3,atributo); opcion_main=1; } funcion.leer_hex=0; } } } } } /*-------------------------------------------VOID INI_PANTALLA (VOID) Funcion que dibuja todas las ventanas y sus contenidos iniciales. --------------------------------------------*/ void ini_pantalla (void){ representar_cuadros (); representar_registros_estatico (0); representar_registros_dinamico (0); representar_menu(); listado(0,0); representar_conversor(); representar_punto_ruptura(); representar_estado (SW1&0X02); } 177 ITF51 /*-------------------------------------------VOID REPRESENTAR_CONVERSOR (VOID) Funcion que representa en pantalla el cuadro del conversor y sus caracteres fijos. --------------------------------------------*/ void representar_conversor (void){ escribir_palabra (6,41,"Conversor",atributo); escribir_palabra (4,43,"DEC",atributo); escribir_palabra (4,45,"HEX",atributo); escribir_palabra (4,47,"BIN",atributo); linea (8,43,10,43,48,atributo); linea (8,45,9,45,48,atributo); linea (8,47,15,47,48,atributo); } /*-------------------------------------------VOID REPRESENTAR_MENU (VOID) Funcion que representa en pantalla el despliegue del menu principal junto con algunos caracteres adicionales. --------------------------------------------*/ void representar_menu (void){ escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (2,5,"PROGRAMA",atributo_inverso); escribir_palabra (2,12,"MEMORIA",atributo); escribir_palabra (2,18,"REGISTROS",atributo); escribir_palabra (2,24,"PUNTO DE RUPTURA",atributo); escribir_palabra (2,29,"UTILIDADES",atributo); escribir_palabra (2,34,"SALIR",atributo); escribir_palabra (5,7,"Ejecutar",atributo); escribir_palabra (5,8,"Paso a Paso",atributo); escribir_palabra (5,9,"Resetear",atributo); escribir_palabra (5,10,"Listar",atributo); escribir_palabra (5,14,"Modificar",atributo); escribir_palabra (5,15,"Transferir",atributo); escribir_palabra (5,20,"Modificar",atributo); escribir_palabra (5,21,"Listar",atributo); escribir_palabra (5,26,"Activar",atributo); escribir_palabra (5,27,"Desactivar",atributo); escribir_palabra (5,31,"Conversor",atributo); escribir_palabra (5,32,"Color",atributo); escribir_car (3,6,179,atributo); escribir_car (3,7,195,atributo); 178 ITF51 escribir_car (3,8,195,atributo); escribir_car (3,9,195,atributo); escribir_car (3,10,192,atributo); escribir_car (3,13,179,atributo); escribir_car (3,14,195,atributo); escribir_car (3,15,192,atributo); escribir_car (3,19,179,atributo); escribir_car (3,20,195,atributo); escribir_car (3,21,192,atributo); escribir_car (3,25,179,atributo); escribir_car (3,26,195,atributo); escribir_car (3,27,192,atributo); escribir_car (3,30,179,atributo); escribir_car (3,31,195,atributo); escribir_car (3,32,192,atributo); linea (4,7,4,10,196,atributo); linea (4,14,4,15,196,atributo); linea (4,20,4,21,196,atributo); linea (4,26,4,27,196,atributo); linea (4,31,4,32,196,atributo); } /*-------------------------------------------VOID REPRESENTAR_EJECUTAR (U_CHAR ACTIVO) Funcion que representa en pantalla el despliegue del menu de ejecucion/paso a paso. Activo=1 Ejecutar-Ultima Activo=2 Ejecutar-Nueva Activo=3 Paso a Paso-Nueva Activo=4 Paso a Paso-Ultima --------------------------------------------*/ void representar_ejecutar (u_char activo){ rectangulo (20,40,60,47,3,atributo); escribir_palabra (28,43,"Elija la direccion de PC:",atributo); escribir_palabra (28,45," -ULTIMA- -NUEVA-",atributo); if (activo<3){ escribir_palabra (34,40,"³ ³",atributo); escribir_palabra (35,40,"EJECUTAR",atributo_inverso); escribir_palabra (34,41,"ÀÄÄÄÄÄÄÄÄÙ",atributo); } else { escribir_palabra (33,40,"³ ³",atributo); 179 ITF51 escribir_palabra (34,40,"PASO A PASO",atributo_inverso); escribir_palabra (33,41,"ÀÄÄÄÄÄÄÄÄÄÄÄÙ",atributo); } if ((activo==1)||(activo==3)){ escribir_palabra (29,45,"-ULTIMA-",atributo_inverso); } else{ escribir_palabra (44,45,"-NUEVA-",atributo_inverso); } } /*-------------------------------------------VOID REPRESENTAR_REGISTROS_ESTATICO (INT ACTIVO) Funcion que representa en pantalla los caracteres fijos dentro del cuadro de registros. Activo selecciona el registro iluminado. --------------------------------------------*/ void representar_registros_estatico (int activo){ t_registros tabla_temp; //Tabla con los atributos int temp; //Variable de ayuda for(temp=0;temp<32;temp++){ tabla_temp[temp]=atributo; } tabla_temp[activo]=atributo_inverso; if (!activo) escribir_palabra (63,2," REGISTROS else if (activo) escribir_palabra (63,2," linea (70,5,70,20,221,atributo); escribir_palabra (66,5,"..",atributo); escribir_palabra (66,6,"..",atributo); escribir_palabra (66,7,"..",atributo); escribir_palabra (66,8,"..",atributo); escribir_palabra (64,9,"....",atributo); escribir_palabra (65,10,"...",atributo); escribir_palabra (65,11,"...",atributo); escribir_palabra (65,12,"...",atributo); escribir_palabra (65,13,"...",atributo); escribir_palabra (65,14,"...",atributo); escribir_palabra (65,15,"...",atributo); escribir_palabra (65,16,"...",atributo); escribir_palabra (67,17,".",atributo); escribir_palabra (67,18,".",atributo); escribir_palabra (66,19,"..",atributo); escribir_palabra (66,20,"..",atributo); 180 ",atributo); REGISTROS ",atributo_inverso); ITF51 escribir_palabra (74,5,"..",atributo); escribir_palabra (74,6,"..",atributo); escribir_palabra (75,7,".",atributo); escribir_palabra (75,8,".",atributo); escribir_palabra (75,9,".",atributo); escribir_palabra (74,10,"..",atributo); escribir_palabra (74,11,"..",atributo); escribir_palabra (73,12,"...",atributo); escribir_palabra (73,13,"...",atributo); escribir_palabra (73,14,"...",atributo); escribir_palabra (73,15,"...",atributo); escribir_palabra (73,16,"...",atributo); escribir_palabra (73,17,"...",atributo); escribir_palabra (73,18,"...",atributo); escribir_palabra (73,19,"...",atributo); escribir_palabra (63,5,"DPH",tabla_temp[1]); escribir_palabra (63,6,"DPL",tabla_temp[2]); escribir_palabra (63,7,"PSW",tabla_temp[3]); escribir_palabra (63,8,"ACC",tabla_temp[4]); escribir_palabra (63,9,"B",tabla_temp[5]); escribir_palabra (63,10,"SP",tabla_temp[6]); escribir_palabra (63,11,"P0",tabla_temp[7]); escribir_palabra (63,12,"P1",tabla_temp[8]); escribir_palabra (63,13,"P2",tabla_temp[9]); escribir_palabra (63,14,"P3",tabla_temp[10]); escribir_palabra (63,15,"IP",tabla_temp[11]); escribir_palabra (63,16,"IE",tabla_temp[12]); escribir_palabra (63,17,"TMOD",tabla_temp[13]); escribir_palabra (63,18,"TCON",tabla_temp[14]); escribir_palabra (63,19,"TH0",tabla_temp[15]); escribir_palabra (63,20,"TL0",tabla_temp[16]); escribir_palabra (71,5,"TH1",tabla_temp[17]); escribir_palabra (71,6,"TL1",tabla_temp[18]); escribir_palabra (71,7,"SCON",tabla_temp[19]); escribir_palabra (71,8,"SBUF",tabla_temp[20]); escribir_palabra (71,9,"PCON",tabla_temp[21]); escribir_palabra (71,10,"PCH",tabla_temp[22]); escribir_palabra (71,11,"PCL",tabla_temp[23]); escribir_palabra (71,12,"R0",tabla_temp[24]); escribir_palabra (71,13,"R1",tabla_temp[25]); escribir_palabra (71,14,"R2",tabla_temp[26]); escribir_palabra (71,15,"R3",tabla_temp[27]); escribir_palabra (71,16,"R4",tabla_temp[28]); 181 ITF51 escribir_palabra (71,17,"R5",tabla_temp[29]); escribir_palabra (71,18,"R6",tabla_temp[30]); escribir_palabra (71,19,"R7",tabla_temp[31]); } /*-------------------------------------------VOID REPRESENTAR_REGISTROS_DINAMICO (INT ACTIVO) Funcion que representa en pantalla el contenido de los registros. Activo selecciona el registro iluminado. --------------------------------------------*/ void representar_registros_dinamico (int activo){ int temp1,temp2; //Variables de ayuda for(temp1=1;temp1<17;temp1++){ //Columna izquierda if (activo==temp1) temp2=1; else if (activo!=temp1) temp2=0; escribir_hex (68,4+temp1,tabla_registros[temp1],temp2); } for(temp1=1;temp1<16;temp1++){ //Columna derecha if ((activo-16)==temp1) temp2=1; else if ((activo-16)!=temp1) temp2=0; escribir_hex (76,4+temp1,tabla_registros[temp1+16],temp2); } } /*-------------------------------------------VOID REPRESENTAR_MENU_MEMORIA (INT ACTIVO) Funcion que representa en pantalla los caracteres fijos en el cuadro secundario del menu del color. Activo=1 Modificar-Programa Activo=2 Modificar-Datos Activo=3 Modificar-Interna --------------------------------------------*/ void representar_menu_memoria (int activo){ rectangulo (20,40,60,47,3,atributo); escribir_palabra (36,40,"³ ³",atributo); escribir_palabra (37,40,"MEMORIA",atributo_inverso); escribir_palabra (36,41,"ÀÄÄÄÄÄÄÄÙ",atributo); escribir_palabra (28,43,"Elegir el tipo de memoria:",atributo); escribir_palabra (25,45,"PROGRAMA DATOS INTERNA",atributo); if (activo==1) escribir_palabra (25,45,"PROGRAMA",atributo_inverso); if (activo==2) escribir_palabra (38,45,"DATOS",atributo_inverso); 182 ITF51 if (activo==3) escribir_palabra (48,45,"INTERNA",atributo_inverso); } /*-------------------------------------------VOID REPRESENTAR_MEMORIA_ESTATICO (INT ACTIVO, INT TIPO_MEMORIA) Funcion que representa en pantalla los caracteres fijos dentro del cuadro de memoria. Activo selecciona el byte iluminado. Tipo_memoria=1 - Programa Tipo_memoria=2 - Datos Tipo_memoria=3 - Interna --------------------------------------------*/ void representar_memoria_estatico (int activo, int tipo_memoria){ int i,pagina; //Variables de ayuda rectangulo (20,4,25,36,3,atributo); rectangulo (20,4,60,4,3,atributo); rectangulo (28,5,28,36,3,atributo); rectangulo (31,5,31,36,3,atributo); rectangulo (34,5,34,36,3,atributo); rectangulo (37,5,37,36,3,atributo); rectangulo (40,5,40,36,3,atributo); rectangulo (43,5,43,36,3,atributo); rectangulo (46,5,46,36,3,atributo); rectangulo (49,5,50,36,3,atributo); rectangulo (59,5,60,36,3,atributo); if (tipo_memoria==1) pagina=cursor.pag_programa; else if (tipo_memoria==2) pagina=cursor.pag_datos; else if (tipo_memoria==3) pagina=cursor.pag_interna; if (!pagina) pagina=1; for(i=0;i<32;i++){ escribir_hex (20,5+i,pagina-1,0); } escribir_palabra (20,4,"ADR@",atributo); escribir_palabra (33,4,"CONTENIDO",atributo); escribir_palabra (52,4,"ASCII",atributo); escribir_palabra (22,5,"00",atributo); escribir_palabra (22,6,"08",atributo); escribir_palabra (22,7,"10",atributo); escribir_palabra (22,8,"18",atributo); escribir_palabra (22,9,"20",atributo); escribir_palabra (22,10,"28",atributo); escribir_palabra (22,11,"30",atributo); escribir_palabra (22,12,"38",atributo); 183 ITF51 escribir_palabra (22,13,"40",atributo); escribir_palabra (22,14,"48",atributo); escribir_palabra (22,15,"50",atributo); escribir_palabra (22,16,"58",atributo); escribir_palabra (22,17,"60",atributo); escribir_palabra (22,18,"68",atributo); escribir_palabra (22,19,"70",atributo); escribir_palabra (22,20,"78",atributo); escribir_palabra (22,21,"80",atributo); escribir_palabra (22,22,"88",atributo); escribir_palabra (22,23,"90",atributo); escribir_palabra (22,24,"98",atributo); escribir_palabra (22,25,"A0",atributo); escribir_palabra (22,26,"A8",atributo); escribir_palabra (22,27,"B0",atributo); escribir_palabra (22,28,"B8",atributo); escribir_palabra (22,29,"C0",atributo); escribir_palabra (22,30,"C8",atributo); escribir_palabra (22,31,"D0",atributo); escribir_palabra (22,32,"D8",atributo); escribir_palabra (22,33,"E0",atributo); escribir_palabra (22,34,"E8",atributo); escribir_palabra (22,35,"F0",atributo); escribir_palabra (22,36,"F8",atributo); linea (60,5,60,36,176,atributo); //Barra de la derecha if (tipo_memoria==1){ //Memoria de programas if (activo) escribir_palabra\ (20,2," MEMORIA DE PROGRAMA ",atributo_inverso); else if (!activo) escribir_palabra\ (20,2," MEMORIA DE PROGRAMA ",atributo); //Cuadro activo en la for(i=0;i<32;i++){ //barra de la derecha if (pagina==(i+1)) escribir_palabra (60,5+i,"°",atributo_inverso); } } if (tipo_memoria==2){ //Memoria de datos if (activo) escribir_palabra\ (20,2," MEMORIA DE DATOS ",atributo_inverso); else if (!activo) escribir_palabra\ (20,2," MEMORIA DE DATOS ",atributo); 184 ITF51 //Cuadro activo en la for(i=0;i<32;i++){ //barra de la derecha if (((pagina-1)/6)==i) escribir_palabra (60,5+i,"°",atributo_inverso); } } if (tipo_memoria==3){ //Memoria interna if (activo) escribir_palabra (20,2," ",atributo_inverso); MEMORIA INTERNA\ else if (!activo) escribir_palabra (20,2," ",atributo); linea (60,5,60,36,176,atributo_inverso); } MEMORIA INTERNA\ //Barra de la derecha //toda activa } /*-------------------------------------------VOID REPRESENTAR_MEMORIA_DINAMICO (INT ACTIVO, INT TIPO_MEMORIA) Funcion que representa en pantalla el contenido de los memoria. Activo selecciona si el registro esta iluminado. Tipo_memoria=1 - Programa Tipo_memoria=2 - Datos Tipo_memoria=3 - Interna --------------------------------------------*/ void representar_memoria_dinamico (int activo, int tipo_memoria){ int i,j,pagina; //Variables de ayuda long posicion=0; if (tipo_memoria==1) pagina=cursor.pag_programa; else if (tipo_memoria==2) pagina=cursor.pag_datos; else if (tipo_memoria==3) pagina=cursor.pag_interna; if (!pagina) pagina=1; if (tipo_memoria==1){ for(j=0;j<32;j++){ //Para todas las filas del cuadro for(i=0;i<8;i++){ //Para todas las columnas del cuadro posicion=i+j*8+(pagina-1)*256; //Busqueda del byte activo //y escritura de todos los //valores en hexadecimal if (activo){ if (cursor.mem_programa==(i+j*8)) escribir_hex\ (3*i+26,j+5,f_leer_caracter(mem_programa,posicion),1); else if (cursor.mem_programa!=(i+j*8)) escribir_hex\ (3*i+26,j+5,f_leer_caracter(mem_programa,posicion),0); } 185 ITF51 else if (!activo){ escribir_hex (3*i+26,j+5,f_leer_caracter(mem_programa,posicion),0); } //Escritura del codigo //ASCII asociado a los //bytes de la memoria if (f_leer_caracter(mem_programa,posicion)){ escribir_car (i+51,j+5,f_leer_caracter(mem_programa,posicion),atributo); } else if (!f_leer_caracter(mem_programa,posicion)){ escribir_car (i+51,j+5,46,atributo); } } } } if (tipo_memoria==2){ for(j=0;j<32;j++){ //Para todas las filas del cuadro for(i=0;i<8;i++){ //Para todas las columnas del cuadro posicion=i+j*8+(pagina-1)*256; //Busqueda del byte activo //y escritura de todos los //valores en hexadecimal if (activo){ if (cursor.mem_datos==(i+j*8)) escribir_hex\ (3*i+26,j+5,f_leer_caracter(mem_datos,posicion),1); else if (cursor.mem_datos!=(i+j*8)) escribir_hex\ (3*i+26,j+5,f_leer_caracter(mem_datos,posicion),0); } else if (!activo){ escribir_hex (3*i+26,j+5,f_leer_caracter(mem_datos,posicion),0); } //Escritura del codigo //ASCII asociado a los //bytes de la memoria if (f_leer_caracter(mem_datos,posicion)){ escribir_car (i+51,j+5,f_leer_caracter(mem_datos,posicion),atributo); } else if ((f_leer_caracter(mem_datos,posicion)&0x000000FF)==0x0000){ escribir_car (i+51,j+5,46,atributo); } } } } 186 ITF51 if (tipo_memoria==3){ for(j=0;j<32;j++){ //Para todas las filas del cuadro for(i=0;i<8;i++){ //Para todas las columnas del cuadro posicion=i+j*8+(pagina-1)*256; //Busqueda del byte activo //y escritura de todos los //valores en hexadecimal if (activo){ if (cursor.mem_interna==(i+j*8)) escribir_hex\ (3*i+26,j+5,f_leer_caracter(mem_interna,posicion),1); else if (cursor.mem_interna!=(i+j*8)) escribir_hex\ (3*i+26,j+5,f_leer_caracter(mem_interna,posicion),0); } else if (!activo){ escribir_hex (3*i+26,j+5,f_leer_caracter(mem_interna,posicion),0); } //Escritura del codigo //ASCII asociado a los //bytes de la memoria if (f_leer_caracter(mem_interna,posicion)){ escribir_car (i+51,j+5,f_leer_caracter(mem_interna,posicion),atributo); } else if (!f_leer_caracter(mem_interna,posicion)){ escribir_car (i+51,j+5,46,atributo); } } } } } /*-------------------------------------------VOID REPRESENTAR_PUNTO_RUPTURA (VOID) Funcion que representa en pantalla los caracteres fijos del cuadro de punto de ruptura asi como el valor de este. --------------------------------------------*/ void representar_punto_ruptura(void){ escribir_palabra (63,24,"PUNTO--RUPTURA",atributo); escribir_palabra (64,27,"Direccion: ",atributo); if (SW1&0x08) escribir_palabra (64,30,"ACTIVADO ",(atributo|0x80)); if (!(SW1&0x08)) escribir_palabra (64,30,"DESACTIVADO 187 ",atributo); ITF51 escribir_hex (74,27,p_ruptura.dph,0); escribir_hex (76,27,p_ruptura.dpl,0); } /*-------------------------------------------VOID REPRESENTAR_CUADROS (VOID) Funcion que representa en pantalla los rectangulos de todo el programa. --------------------------------------------*/ void representar_cuadros (void){ rectangulo (0,0,79,49,2,atributo); //cuadros exteriores rectangulo (1,1,78,48,3,atributo); rectangulo (1,1,18,37,1,atributo); //cuadro menu escribir_car (1,3,195,atributo); escribir_car (18,3,180,atributo); linea (2,3,17,3,196,atributo); rectangulo (62,1,78,22,1,atributo); //cuadro registros escribir_car (62,3,195,atributo); escribir_car (78,3,180,atributo); linea (63,3,77,3,196,atributo); rectangulo (62,23,78,32,1,atributo); //cuadro punto-ruptura escribir_car (62,25,195,atributo); escribir_car (78,25,180,atributo); linea (63,25,77,25,196,atributo); rectangulo (19,39,61,48,1,atributo); //cuadro secundario rectangulo (20,40,60,47,3,atributo); rectangulo (2,39,17,48,1,atributo); //cuadro conversor rectangulo (19,1,61,37,1,atributo); //cuadro memoria escribir_car (19,3,195,atributo); escribir_car (61,3,180,atributo); linea (20,3,60,3,196,atributo); rectangulo (62,42,78,48,1,atributo); //cuadro programador escribir_palabra (63,44,"Programado por",atributo); escribir_palabra (64,46,"EDUARD SARDA",atributo); } /*-------------------------------------------VOID REPRESENTAR_ESTADO (INT OPCION) Funcion que representa en pantalla el contenido del cuadro de estado del programa, pudiendose selecionar el modo (0-Paro, 2-Marcha). --------------------------------------------*/ void representar_estado (int opcion){ 188 ITF51 rectangulo (62,33,78,40,1,atributo); escribir_palabra (64,34,"E",atributo); escribir_palabra (64,35,"s",atributo); escribir_palabra (64,36,"t ___",atributo); escribir_palabra (64,37,"a",atributo); escribir_palabra (64,38,"d",atributo); escribir_palabra (64,39,"o",atributo); rectangulo (69,35,70,38,3,atributo); escribir_palabra (71,35,"PARADO",atributo); escribir_palabra (71,38,"MARCHA",atributo); switch (opcion){ case 0: funcion.espera=0; escribir_palabra (71,35,"PARADO",atributo_inverso); escribir_palabra (69,36,"/",atributo); escribir_palabra (70,35,"/",atributo); break; case 2: funcion.espera=20; escribir_palabra (71,38,"MARCHA",atributo_inverso); escribir_palabra (69,37,"\\",atributo); escribir_palabra (70,38,"\\",atributo); break; } } /*-------------------------------------------VOID REPRESENTAR_MENU_CONVERSOR (INT ACTIVO) Funcion que representa en pantalla los caracteres fijos en el cuadro secundario del menu del conversor. Activo=1 - Decimal Activo=2 - Hexadecimal Activo=3 - Binario --------------------------------------------*/ void representar_menu_conversor (int activo){ escribir_palabra (35,40,"³ ³",atributo); escribir_palabra (36,40,"CONVERSOR",atributo_inverso); escribir_palabra (35,41,"ÀÄÄÄÄÄÄÄÄÄÙ",atributo); escribir_palabra (21,43,"Numero entrante en: DEC escribir_palabra (21,46,"Valor: HEX BIN",atributo); ",atributo); if (activo==1){ 189 ITF51 escribir_palabra (41,43,"DEC",atributo_inverso); escribir_palabra (27,46,"(de 0 a 255)",atributo); } if (activo==2){ escribir_palabra(46,43,"HEX",atributo_inverso); escribir_palabra (27,46,"(de 00 a FF)",atributo); } if (activo==3){ escribir_palabra(51,43,"BIN",atributo_inverso); escribir_palabra (27,46,"(de 00 a FF)",atributo); } } /*-------------------------------------------VOID REPRESENTAR_COLOR (INT ACTIVO) Funcion que representa en pantalla los caracteres fijos en el cuadro secundario del menu del color. Activo del 1 al 8: FONDO Activo del 9 al 22: TEXTO --------------------------------------------*/ void representar_color (int activo){ rectangulo (34,42,60,47,3,atributo); escribir_palabra (37,40,"³ ³",atributo); escribir_palabra (38,40,"COLOR",atributo_inverso); escribir_palabra (37,41,"ÀÄÄÄÄÄÙ",atributo); linea (33,42,33,47,221,atributo); escribir_palabra (20,43,"FONDO:",atributo); escribir_palabra (20,46,"TEXTO:",atributo); if (activo<9){ escribir_palabra (20,46," ",atributo); rectangulo (26,43,32,46,3,atributo); escribir_palabra (35,43,"Negro Rojo",atributo); escribir_palabra (35,44,"Azul Magenta",atributo); escribir_palabra (35,45,"Verde Marron",atributo); escribir_palabra (35,46,"Cyan Gris c.",atributo); switch (activo){ case 1: escribir_palabra (35,43,"Negro",atributo_inverso); break; case 5: escribir_palabra (42,43,"Rojo",atributo_inverso); break; 190 ITF51 case 2: escribir_palabra (35,44,"Azul",atributo_inverso); break; case 6: escribir_palabra (42,44,"Magenta",atributo_inverso); break; case 3: escribir_palabra (35,45,"Verde",atributo_inverso); break; case 7: escribir_palabra (42,45,"Marron",atributo_inverso); break; case 4: escribir_palabra (35,46,"Cyan",atributo_inverso); break; case 8: escribir_palabra (42,46,"Gris c.",atributo_inverso); break; } } if ((activo>8)&&(activo<23)){ escribir_palabra (35,42,"Negro Marron Rojo c.",atributo); escribir_palabra (35,43,"Azul Gris c. Magenta c.",atributo); escribir_palabra (35,44,"Verde Gris o.",atributo); escribir_palabra (35,45,"Cyan Azul c.",atributo); escribir_palabra (35,46,"Rojo Verde c.",atributo); escribir_palabra (35,47,"Magenta Cyan c.",atributo); switch (activo){ case 9: escribir_palabra (35,42,"Negro",atributo_inverso); break; case 15: escribir_palabra (43,42,"Marron",atributo_inverso); break; case 21: escribir_palabra (51,42,"Rojo c.",atributo_inverso); break; case 10: escribir_palabra (35,43,"Azul",atributo_inverso); break; case 16: escribir_palabra (43,43,"Gris c.",atributo_inverso); break; 191 ITF51 case 22: escribir_palabra (51,43,"Magenta c.",atributo_inverso); break; case 11: escribir_palabra (35,44,"Verde",atributo_inverso); break; case 17: escribir_palabra (43,44,"Gris o.",atributo_inverso); break; case 12: escribir_palabra (35,45,"Cyan",atributo_inverso); break; case 18: escribir_palabra (43,45,"Azul c.",atributo_inverso); break; case 13: escribir_palabra (35,46,"Rojo",atributo_inverso); break; case 19: escribir_palabra (43,46,"Verde c.",atributo_inverso); break; case 14: escribir_palabra (35,47,"Magenta",atributo_inverso); break; case 20: escribir_palabra (43,47,"Cyan c.",atributo_inverso); break; } } } /***************************************************** VOID REPRESENTAR_PRESENTACION (VOID); Dibuja la pantalla de inicio con el nombre del proyecto y del autor. *****************************************************/ void representar_presentacion (void){ rectangulo (0,0,79,49,3,atributo); escribir_palabra (28,2,"ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿",atributo); escribir_palabra (28,3,"³ ³",atributo); escribir_palabra (28,4,"³ ³",atributo); escribir_palabra (28,5,"³ ²²² ²²²²² escribir_palabra (28,6,"³ ² ² ²²²² ³",atributo); ² ³",atributo); 192 ITF51 escribir_palabra (28,7,"³ ² ² ² ³",atributo); escribir_palabra (28,8,"³ ² ² ²²² ³",atributo); escribir_palabra (28,9,"³ ² ² ² ³",atributo); escribir_palabra(28,10,"³ ² ² ² ³",atributo); escribir_palabra(28,11,"³ ²²² ² ² ³",atributo); escribir_palabra(28,12,"³ ³",atributo); escribir_palabra(28,13,"³ ³",atributo); escribir_palabra(28,14,"³ ²²²² ²² ³",atributo); escribir_palabra(28,15,"³ ² ² ³",atributo); escribir_palabra(28,16,"³ ²²²² ² ³",atributo); escribir_palabra(28,17,"³ ² ² ³",atributo); escribir_palabra(28,18,"³ ²²²² ²²² ³",atributo); escribir_palabra(28,19,"³ ³",atributo); escribir_palabra(28,20,"³ ³",atributo); escribir_palabra(28,21,"ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ",atributo); escribir_palabra(38,30,"POR",atributo); escribir_palabra(26,32,"Úij¿³³Ú¿Ú¿³¿",atributo); escribir_palabra(26,33,"à ³³³³Ã´ÃÙ³³",atributo); escribir_palabra(26,34,"ÀijÙÀÙ³³³\\³Ù",atributo); escribir_palabra(41,32,"ÚÄÚ¿Ú¿³¿Ú¿",atributo); escribir_palabra(41,33,"À¿Ã´ÃÙ³³Ã´",atributo); escribir_palabra(41,34,"ÄÙ³³³\\³Ù³³",atributo); escribir_palabra(22,45,"- Pulse una tecla para continuar -",atributo|0x80); } /*-------------------------------------------VOID FIN_SEGURIDAD (VOID) Funcion que representa en pantalla el cuadro de salida (Si o No). --------------------------------------------*/ void fin_seguridad (void){ escribir_palabra (2,2," M E N U ",atributo); rectangulo (29,41,51,45,1,atributo_inverso); rectangulo (30,42,50,44,3,atributo_inverso); escribir_palabra (30,41," - - - - - - - - - - ",atributo_inverso); escribir_palabra (30,45," - - - - - - - - - - ",atributo_inverso); escribir_palabra (29,42," ",atributo_inverso); escribir_palabra (29,44," ",atributo_inverso); escribir_palabra (51,42," ",atributo_inverso); escribir_palabra (51,44," ",atributo_inverso); escribir_palabra (30,42,"ABANDONAR EL PROGRAMA",atributo_inverso); escribir_palabra (39,44,"S/N",atributo_inverso); } 193 ITF51 /*-------------------------------------------VOID ESCRIBIR_HEX (INT X, INT Y, LONG VALOR, INT INVERSO) Funcion que representa en pantalla un valor en hexadecimal, pudiendo selecionar la posicion x,y y si esta iluminado (inverso=1). --------------------------------------------*/ void escribir_hex (int x, int y, long valor,int inverso){ char temp,temp2; //Variables de ayuda temp=((valor&(0xF0))>>4); if (inverso) temp2=atributo_inverso; else if (!inverso) temp2=atributo; switch (temp){ case 0: escribir_car (x,y,48,temp2); break; case 1: escribir_car (x,y,49,temp2); break; case 2: escribir_car (x,y,50,temp2); break; case 3: escribir_car (x,y,51,temp2); break; case 4: escribir_car (x,y,52,temp2); break; case 5: escribir_car (x,y,53,temp2); break; case 6: escribir_car (x,y,54,temp2); break; case 7: escribir_car (x,y,55,temp2); break; case 8: escribir_car (x,y,56,temp2); break; case 9: escribir_car (x,y,57,temp2); break; 194 ITF51 case 10: escribir_car (x,y,65,temp2); break; case 11: escribir_car (x,y,66,temp2); break; case 12: escribir_car (x,y,67,temp2); break; case 13: escribir_car (x,y,68,temp2); break; case 14: escribir_car (x,y,69,temp2); break; case 15: escribir_car (x,y,70,temp2); break; } temp=valor&(0x0F); switch (temp){ case 0: escribir_car (x+1,y,48,temp2); break; case 1: escribir_car (x+1,y,49,temp2); break; case 2: escribir_car (x+1,y,50,temp2); break; case 3: escribir_car (x+1,y,51,temp2); break; case 4: escribir_car (x+1,y,52,temp2); break; case 5: escribir_car (x+1,y,53,temp2); break; case 6: escribir_car (x+1,y,54,temp2); break; case 7: 195 ITF51 escribir_car (x+1,y,55,temp2); break; case 8: escribir_car (x+1,y,56,temp2); break; case 9: escribir_car (x+1,y,57,temp2); break; case 10: escribir_car (x+1,y,65,temp2); break; case 11: escribir_car (x+1,y,66,temp2); break; case 12: escribir_car (x+1,y,67,temp2); break; case 13: escribir_car (x+1,y,68,temp2); break; case 14: escribir_car (x+1,y,69,temp2); break; case 15: escribir_car (x+1,y,70,temp2); break; } } /*-------------------------------------------VOID ESCRIBIR_DEC (INT X, INT Y, LONG VALOR) Funcion que representa en pantalla un valor en decimal, pudiendo selecionar la posicion x-y. ----------------------------------------------*/ void escribir_dec (int x, int y, long valor){ long temp1,temp2,temp3; //Variables de ayuda valor=valor&0x00FF; temp1=valor%10; temp2=((valor-temp1)%100)/10; temp3=((valor-temp2-temp1)%1000)/100; escribir_car (x,y,temp3+48,atributo); escribir_car (x+1,y,temp2+48,atributo); escribir_car (x+2,y,temp1+48,atributo); 196 ITF51 } /*-------------------------------------------VOID ESCRIBIR_BIN (INT X, INT Y, LONG VALOR) Funcion que representa en pantalla un valor en binario, pudiendo selecionar la posicion x-y. ----------------------------------------------*/ void escribir_bin (int x, int y, long valor){ long aux; //Variables de ayuda int i,j; valor=valor&0x00FF; i=128; j=0; while (j!=8){ aux=(valor&i)/i; escribir_car(x+j,y,aux+48,atributo); j++; i=i/2; } } /*-----------------------------------------------------------VOID REPRESENTAR_ERROR (U_CHAR OPCION); Dibuja en el cuadro secundario un mensaje de error ------------------------------------------------------------*/ void representar_error (u_char opcion){ rectangulo (20,42,60,47,3,atributo); escribir_palabra (27,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (27,46,"Pulse ENTER para continuar",atributo); escribir_palabra (33,46,"ENTER",atributo|0x80); switch (opcion) { case 1: escribir_palabra (21,43,"ERROR: No existe ",atributo); escribir_palabra (38,43,datos,atributo); break; case 2: escribir_palabra (21,43,"ERROR: Memoria de datos no encontrada",atributo); break; case 3: escribir_palabra (21,43,"ERROR: El emulador no responde",atributo); break; case 4: 197 ITF51 escribir_palabra (21,43,"ERROR: Transmision incorrecta",atributo); break; case 5: escribir_palabra (21,43,"ERROR: Direccion de destino incorrecta",atributo); break; case 6: escribir_palabra (21,43,"ERROR: No se ha seleccionado ningun",atributo); escribir_palabra (21,44," ARCHIVO.TSK",atributo); break; case 7: escribir_palabra (21,43,"ERROR: Punto de ruptura incorrecto",atributo); break; case 8: escribir_palabra (21,43,"ERROR: El registro no se puede\ modificar",atributo); break; case 9: escribir_palabra (21,43,"ERROR: Solo se puede modificar",atributo); escribir_palabra (21,44," desde 00h hasta 7Fh",atributo); break; case 10: escribir_palabra (21,43,"ERROR: Ejecucion incorrecta",atributo); break; case 11: escribir_palabra (21,43,"ERROR: Paso incorrecto",atributo); break; case 12: escribir_palabra (21,43,"ERROR: Programa NO transferido",atributo); break; } } /*-----------------------------------------------------------VOID REPRESENTAR_OK (U_CHAR OPCION); Dibuja en el cuadro secundario un mensaje de error ------------------------------------------------------------*/ void representar_ok (u_char opcion){ rectangulo (20,42,60,47,3,atributo); escribir_palabra (27,45,"- - - - - - - - - - - - -",atributo); escribir_palabra (27,46,"Pulse ENTER para continuar",atributo); escribir_palabra (33,46,"ENTER",atributo|0x80); switch (opcion) { 198 ITF51 case 1: escribir_palabra (24,43,"OK: Transmision de programa correcto",atributo); break; case 2: escribir_palabra (24,43,"OK: Transmision de datos correcto",atributo); break; case 3: escribir_palabra (24,43,"OK: Punto de Ruptura activado",atributo); break; case 4: escribir_palabra (24,43,"OK: Transmision de registro correcto",atributo); break; case 5: escribir_palabra (24,43,"OK: Transmision correcta",atributo); break; case 6: escribir_palabra (24,43,"OK: Programa ejecutado",atributo); break; case 7: escribir_palabra (24,43,"OK: Paso ejecutado",atributo); break; case 8: escribir_palabra (24,43,"OK: Sistema reseteado",atributo); break; case 9: escribir_palabra (24,43,"OK: Se ha llegado al punto de ruptura",atributo); break; case 10: escribir_palabra (24,43,"OK: Ejecucion detenida",atributo); break; } } /*------------------------------------------------------------------------------INT SUB3320 (INT TIPO_MEM); Comprueba el estado de las comunicaciones y crea una ruta en el hardware hacia memoria de programa (mem=1) o de datos (mem=2). -------------------------------------------------------------------------------*/ int sub3320 (int mem){ u_char xn; xn=inportb(PORTC); 199 ITF51 st.count=18; //Cargamos el contador a 18 tics st.fin=0; //Encendemos el contador //Esperamos un maximo de 18 tics //a que IBF se ponga a 1. //(nuevo dato entrante en espera) while ((!st.fin)&&!(xn&0x20)) xn=inportb(PORTC); if (st.fin){ //Si ha expirado el tiempo return(4); } //Si IBF es 1 else if (!st.fin){ st.fin=1; //Paramos el contador if (mem==1) outportb(PORTC,(inportb(PORTC)&0xFD)); //Crea una ruta en el hardware //hacia la mem_programa else if ((mem==2)||(mem==3)) outportb(PORTC,(inportb(PORTC)|0x02)); //Crea una ruta en el hardware //hacia la mem_datos retardo(1); xn=inportb(PORTA); //Captura PORTA, restaura IBF a 0. if (mem!=3){ //Si no estamos en ejecutar o //en paso a paso outportb(PORTA,0x00); //Escribe en PORTA, pone !OBF a 0. retardo(1); } return(0); } return(0); } /*------------------------------------------------------------------------------INT SUB3140 (VOID); Espera a que el 8051 lea el dato enviado por el PC -------------------------------------------------------------------------------*/ int sub3140 (void){ u_char xn; xn=inportb(PORTC); st.count=10; //Cargamos el contador a 10 tics st.fin=0; //Encendemos el contador //Comprovamos que !OBF vuelva a 1 //esperando un maximo de 10 tics while ((!st.fin)&&!(xn&0x80)) xn=inportb(PORTC); if (st.fin){ //Si ha expirado el tiempo 200 ITF51 return(5); } else if(!st.fin){ //Si !OBF=1 st.fin=1; //Paramos el contador } return(0); } /*------------------------------------------------------------------INT SUB3100 (VOID); Espera a que el 8051 escriba un dato para el PC -------------------------------------------------------------------*/ int sub3100 (void){ u_char xn; xn=inportb(PORTC); st.count=10; //Cargamos el contador a 10 tics st.fin=0; //Encendemos el contador //Comprovamos que IBF se ponga a 1 //esperando un maximo de 10 tics while ((!st.fin)&&!(xn&0x20)) xn=inportb(PORTC); if (st.fin){ //Si ha expirado el tiempo return(6); } else if(!st.fin){ //Si IBF=1 st.fin=1; //Paramos el contador } return(0); } /*--------------------------------------------------------------INT INI_COM (VOID); Activa el puerto de comunicaciones (8255) como bidireccional. Inicializa el program counter. ------------------------------------------------------------------*/ int ini_com (void){ u_char xn; int error; inhibir_int_teclado (); //Deshabilitar la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiar el recuadro secundario funcion.espera=1; //Animacion "COMUNICANDO" activa 201 ITF51 error=0; outportb(CONTROL_WORD,0xC0); //Configuracion del 82C55A en la //targeta de comunicaciones. retardo(9); outportb(PORTC,0xFC); //Flanco en el PORTC bit0, retardo(9); //en el se¤al de RESET outportb(PORTC,0xFD); retardo(9); outportb(PORTA,0xFF); //Escribe en PORTA, pone !OBF a 0. error=sub3320(1); if (error) return(4); //Si ha expirado el tiempo error=sub3320(1); if (error) return(4); //Si ha expirado el tiempo outportb(PORTA,0x00); //Escribe servicio0 en PORTA,!OBF=0. error=sub3140(); //Espera a que el emulador lea if (error) return(4); //Si ha expirado el tiempo error=sub3320(1); if (error) return(4); //Si ha expirado el tiempo return(0); } /*-------------------------------------------------------------INT TRANS (VOID); Función que gestiona todas las transmisiones (segun com.opción). Servicio 1: EJECUCION PASO A PASO Dat1=Direccion-H Dat2=Direccion-L Servicio 2: TRANSFERENCIA DESDE PC A MEMORIA DEL EMULADOR Dat1=Direccion Inicio_H Dat2=Direccion Inicio_L Dat3=Direccion Fin_H Dat4=Direccion Fin_L Servicio 4: TRANSFERENCIA DE LOS REGISTROS INTERNOS DEL MICROCONTROLADOR AL PC Servicio 5: EJECUCION DEL CODIGO SIN PUNTO DE RUPTURA Dat1=Direccion_H Dat2=Direccion_L Servicio 6: TRANSFERENCIA DE MEMORIA INTERNA DEL MICROCONTROLADOR AL PC Servicio 8: MODIFICACION DE UNA POSICION DE MEMORIA DEL EMULADOR Dat1=Direccion_H Dat2=Direccion_L Dat3=Dato 202 ITF51 Servicio 9: MODIFICACION DE UNA POSICION DE MEMORIA INTERNA DEL MICROCONTROLADOR Dat1=Direccion interna Dat2=Dato Servicio 11: MODIFICACION DE REGISTROS ESPECIALES Dat1=Direccion Interna Dat2=Dato Servicio 14: EJECUCION DE CODIGO CON PUNTO DE RUPTURA (1RA PARTE) Dat1=Direccion_H Dat2=Direccion_L Dat3=Punto ruptura_H Dat4=Punto ruptura_L Servicio 15: EJECUCION DE CODIGO CON PUNTO DE RUPTURA (2DA PARTE) --------------------------------------------------------------*/ int trans (u_int dat1, u_int dat2, u_int dat3, u_int dat4, u_char mem, u_char opcion){ u_int error; //Offsetpro: direccion de inicio inhibir_int_teclado (); //Deshabilitar la INT de teclado rectangulo (20,40,60,47,3,atributo); //Limpiar el recuadro secundario funcion.espera=1; //Animacion "COMUNICANDO" activa switch (opcion){ case 1: //EJECUCION PASO A PASO error=servicio1(dat1,dat2); if (error) return(error); //Si ha expirado el tiempo break; case 2: //TRANSFERENCIA DESDE PC A MEMORIA DEL EMULADOR error=servicio2(dat1,dat2,dat3,dat4); if (error) return(error); //Si ha expirado el tiempo break; case 4: //TRANSFERENCIA DE LOS REGISTROS INTERNOS DEL MICROCONTROLADOR AL PC error=servicio4(); if (error) return(error); //Si ha expirado el tiempo break; case 5: //EJECUCION DEL CODIGO SIN PUNTO DE RUPTURA error=servicio5(dat1,dat2); if (error) return(error); //Si ha expirado el tiempo break; case 6: //TRANSFERENCIA DE MEMORIA INTERNA DEL MICROCONTROLADOR AL PC error=servicio6(); if (error) return(error); //Si ha expirado el tiempo break; case 8: //MODIFICACION DE UNA POSICION DE MEMORIA DEL EMULADOR 203 ITF51 error=servicio8(dat1,dat2,dat3,mem); if (error) return(error); //Si ha expirado el tiempo break; case 9: //MODIFICACION DE UNA POSICION DE MEMORIA INTERNA DEL //MICROCONTROLADOR error=servicio9(dat1,dat2); if (error) return(error); //Si ha expirado el tiempo break; case 11: //MODIFICACION DE REGISTROS ESPECIALES error=servicio11(dat1,dat2); if (error) return(error); //Si ha expirado el tiempo break; case 14: //EJECUCION DE CODIGO CON PUNTO DE RUPTURA (1RA PARTE) error=servicio14(dat1,dat2,dat3,dat4); if (error) return(error); //Si ha expirado el tiempo break; case 15: //EJECUCION DE CODIGO CON PUNTO DE RUPTURA (2DA PARTE) error=servicio15(); if (error) return(error); //Si ha expirado el tiempo break; } return(0); } /*************************************************************** INT SERVICIO1 (U_CHAR DIR_H, U_CHAR DIR_L); "Ejecucion Paso a Paso" **************************************************************/ int servicio1 (u_char dir_h, u_char dir_l){ int error; error=0; outportb(PORTA,0xFF); //Escribe XXh en PORTA,!OBF=0 error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,0x01); //Escribe servicio1 en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,dir_l); //Escribe Dir_L en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea outportb(PORTA,dir_h); //Escribe Dir_H en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea 204 ITF51 error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(3); if (error) return(error); //Si ha expirado el tiempo return(0); } /*************************************************************** INT SERVICIO2 (U_CHAR INI_H, U_CHAR INI_L, U_CHAR FIN_H, U_CHAR FIN_L); "Transferencia desde PC a Memoria del Emulador" **************************************************************/ int servicio2 (u_char ini_h, u_char ini_l, u_char fin_h, u_char fin_l){ int xn,i,j,error,offsetpro; error=0; outportb(PORTA,0xFF); //Escribe XXh en PORTA,!OBF=0 error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,0x02); //Escribe servicio2 en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,ini_h); //Escribe Ini_H en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,ini_l); //Escribe Ini_L en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,fin_h); //Escribe Fin_H en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,fin_l); //Escribe Fin_L en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo j=((fin_h*256)+fin_l)-((ini_h*256)+ini_l); //J=tama¤o de la transferencia for(i=0;i<=j;i++){ xn=f_leer_caracter(pro_original,i); //Cargar datos desde el *.TSK outportb(PORTA,xn); //Escribe en PORTA, pone !OBF a 0. error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo error=sub3100(); //Espera a que el emulador escriba if (error) return(error); //Si ha expirado el tiempo com.dl=inportb(PORTA); //Captura PORTA, restaura IBF a 0. 205 ITF51 if (com.dl!=xn) return(8); //Si dato_recibido!=dato_enviado outportb(PORTA,0x00); //Escribe 00h en PORTA,!OBF=0 } offsetpro=((ini_h*256)+ini_l); //Direccion de Inicio (H+L) for(i=0;i<=j;i++){ xn=f_leer_caracter(pro_original,i); //Guardamos el contenido en el //archivo que representa la //memoria de programa f_escribir_caracter(xn,mem_programa,i+offsetpro); } error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(1); return(0); } /*************************************************************** INT SERVICIO4 (VOID); "Transferencia de los Registros Internos del Microcontrolador al PC" **************************************************************/ int servicio4 (void){ int error,xn,i; error=0; outportb(PORTA,0xFF); //Escribe FFh en PORTA,!OBF=0 error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,0x04); //Escribe servicio4 en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo for(i=1;i<=19;i++){ //Devuelve 19 registros error=sub3100(); //Espera a que el emulador escriba if (error) return(error); //Si ha expirado el tiempo xn=inportb(PORTA); //Captura PORTA, restaura IBF a 0. if (i==1){ //Registro - DPH if (xn==tabla_registros[1]) tabla_registros[1]=xn; else { //Comprovacion si ha cambiado tabla_registros[1]=xn; //el contenido escribir_hex (68,5,tabla_registros[1],1); } } if (i==2){ //Registro - DPL 206 ITF51 if (xn==tabla_registros[2]) tabla_registros[2]=xn; else { //Comprovacion si ha cambiado tabla_registros[2]=xn; //el contenido escribir_hex (68,6,tabla_registros[2],1); } } if (i==3){ //Registro - R7 if (xn==tabla_registros[31]) tabla_registros[31]=xn; else { //Comprovacion si ha cambiado tabla_registros[31]=xn; //el contenido escribir_hex (76,19,tabla_registros[31],1); } f_escribir_caracter(xn,mem_interna,7); } if (i==4){ //Registro - R6 if (xn==tabla_registros[30]) tabla_registros[30]=xn; else { //Comprovacion si ha cambiado tabla_registros[30]=xn; //el contenido escribir_hex (76,18,tabla_registros[30],1); } f_escribir_caracter(xn,mem_interna,6); } if (i==5){ //Registro - R5 if (xn==tabla_registros[29]) tabla_registros[29]=xn; else { //Comprovacion si ha cambiado tabla_registros[29]=xn; //el contenido escribir_hex (76,17,tabla_registros[29],1); } f_escribir_caracter(xn,mem_interna,5); } if (i==6){ //Registro - R4 if (xn==tabla_registros[28]) tabla_registros[28]=xn; else { //Comprovacion si ha cambiado tabla_registros[28]=xn; //el contenido escribir_hex (76,16,tabla_registros[28],1); } f_escribir_caracter(xn,mem_interna,4); } if (i==7){ //Registro - R3 if (xn==tabla_registros[27]) tabla_registros[27]=xn; else { //Comprovacion si ha cambiado tabla_registros[27]=xn; //el contenido escribir_hex (76,15,tabla_registros[27],1); 207 ITF51 } f_escribir_caracter(xn,mem_interna,3); } if (i==8){ //Registro - R2 if (xn==tabla_registros[26]) tabla_registros[26]=xn; else { //Comprovacion si ha cambiado tabla_registros[26]=xn; //el contenido escribir_hex (76,14,tabla_registros[26],1); } f_escribir_caracter(xn,mem_interna,2); } if (i==9){ //Registro - R1 if (xn==tabla_registros[25]) tabla_registros[25]=xn; else { //Comprovacion si ha cambiado tabla_registros[25]=xn; //el contenido escribir_hex (76,13,tabla_registros[25],1); } f_escribir_caracter(xn,mem_interna,1); } if (i==10){ //Registro - R0 if (xn==tabla_registros[24]) tabla_registros[24]=xn; else { //Comprovacion si ha cambiado tabla_registros[24]=xn; //el contenido escribir_hex (76,12,tabla_registros[24],1); } f_escribir_caracter(xn,mem_interna,0); } if (i==11){ //Registro - B if (xn==tabla_registros[5]) tabla_registros[5]=xn; else { //Comprovacion si ha cambiado tabla_registros[5]=xn; //el contenido escribir_hex (68,9,tabla_registros[5],1); } } if (i==12){ //Registro - PSW if (xn==tabla_registros[3]) tabla_registros[3]=xn; else { //Comprovacion si ha cambiado tabla_registros[3]=xn; //el contenido escribir_hex (68,7,tabla_registros[3],1); } } if (i==13){ //Registro - PCH if (xn==tabla_registros[22]) tabla_registros[22]=xn; 208 ITF51 else { //Comprovacion si ha cambiado tabla_registros[22]=xn; //el contenido escribir_hex (76,10,tabla_registros[22],1); } } if (i==14){ //Registro - PCL if (xn==tabla_registros[23]) tabla_registros[23]=xn; else { //Comprovacion si ha cambiado tabla_registros[23]=xn; //el contenido escribir_hex (76,11,tabla_registros[23],1); } } if (i==15){ //Registro - SP if (xn==tabla_registros[6]) tabla_registros[6]=xn; else { //Comprovacion si ha cambiado tabla_registros[6]=xn; //el contenido escribir_hex (68,10,tabla_registros[6],1); } } if (i==19){ //Registro - ACC if (xn==tabla_registros[4]) tabla_registros[4]=xn; else { //Comprovacion si ha cambiado tabla_registros[4]=xn; //el contenido escribir_hex (68,8,tabla_registros[4],1); } } outportb(PORTA,0xFF); //Escribe FFh en PORTA,!OBF=0 } outportb(PORTA,0x00); //Escribe 00h en PORTA,!OBF=0 error=sub3320(1); error=sub3320(3); if (error) return(error); //Si ha expirado el tiempo return(0); } /*************************************************************** INT SERVICIO5 (U_CHAR DIR_H, U_CHAR DIR_L); "Ejecucion del Codigo sin Punto de Ruptura" **************************************************************/ int servicio5 (u_char dir_h, u_char dir_l){ int error; error=0; outportb(PORTA,0xFF); //Escribe FFh en PORTA,!OBF=0 209 ITF51 error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,0x05); //Escribe servicio5 en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo retardo(3); outportb(PORTA,dir_l); //Escribe Dir_L en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea retardo(3); outportb(PORTA,dir_h); //Escribe Dir_H en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(2); if (error) return(error); //Si ha expirado el tiempo return(0); } /*************************************************************** INT SERVICIO6 (VOID); "Transferencia de Memoria Interna del Microcontrolador al PC" **************************************************************/ int servicio6 (void){ int error,xn,i; error=0; outportb(PORTA,0xFF); //Escribe FFh en PORTA,!OBF=0 error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,0x06); //Escribe servicio6 en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo for(i=1;i<=23;i++){ //Devuelve 23 registros ordenados //igual que la tabla_registros error=sub3100(); //Espera a que el emulador escriba if (error) return(error); //Si ha expirado el tiempo tabla_registros[i]=inportb(PORTA); //Captura PORTA, restaura IBF a 0. outportb(PORTA,0xFF); //Escribe FFh en PORTA,!OBF=0 } for(i=0x7F;i>=0;i--){ //Devuelve 7Fh bytes de la memoria 210 ITF51 //interna. Los 8 primeros son los //registros R0-R7 error=sub3100(); //Espera a que el emulador escriba if (error) return(error); //Si ha expirado el tiempo xn=inportb(PORTA); //Captura PORTA, restaura IBF a 0. f_escribir_caracter(xn,mem_interna,i); //Guardar byte en mem_interna if (i<=7) tabla_registros[24+i]=xn; //Registros R0-R7 outportb(PORTA,0xFF); //Escribe FFh en PORTA,!OBF=0 } outportb(PORTA,0x00); //Escribe 00h en PORTA,!OBF=0 error=sub3320(1); return(0); } /*************************************************************** INT SERVICIO8 (U_CHAR DIR_H, U_CHAR DIR_L, U_CHAR DATO, U_CHAR MEM); "Modificacion de una Posicion de Memoria del Emulador" **************************************************************/ int servicio8 (u_char dir_h, u_char dir_l, u_char dato, u_char mem){ int error; error=0; outportb(PORTA,0xFF); //Escribe FFh en PORTA,!OBF=0 error=sub3320(mem); if (error) return(error); //Si ha expirado el tiempo error=sub3320(mem); if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,0x08); //Escribe servicio8 en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,dir_h); //Escribe Dir_H en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,dir_l); //Escribe Dir_L en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,dato); //Escribe Dato en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo error=sub3100(); //Espera a que el emulador escriba if (error) return(error); //Si ha expirado el tiempo com.dl=inportb(PORTA); //Captura PORTA, restaura IBF a 0. if (com.dl!=dato) error=1; //Si dato_recibido!=dato_enviado outportb(PORTA,0x00); //Escribe 00h en PORTA,!OBF=0 211 ITF51 sub3320(mem); if (error) return(error); //Si ha expirado el tiempo return(0); } /*************************************************************** INT SERVICIO9 (U_CHAR DIR, U_CHAR DATO); "Modificacion de una Posicion de la Memoria Interna del Microcontrolador" **************************************************************/ int servicio9 (u_char dir, u_char dato){ int error; error=0; outportb(PORTA,0xFF); //Escribe FFh en PORTA,!OBF=0 error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,0x09); //Escribe servicio9 en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,dir); //Escribe Direc. en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,dato); //Escribe Dato en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo error=sub3100(); //Espera a que el emulador escriba if (error) return(error); //Si ha expirado el tiempo com.dl=inportb(PORTA); //Captura PORTA, restaura IBF a 0. outportb(PORTA,0x00); //Escribe 00h en PORTA,!OBF=0 error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo if (com.dl!=dato) error=1; //Si dato_recibido!=dato_enviado if (error) return(error); //Si ha expirado el tiempo return(0); } /*************************************************************** INT SERVICIO11 (U_CHAR DIR, U_CHAR DATO); "Modificacion de Registros Especiales" **************************************************************/ int servicio11 (u_char dir, u_char dato){ int error; 212 ITF51 error=0; outportb(PORTA,0xFF); //Escribe FFh en PORTA,!OBF=0 error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,0x0B); //Escribe servicio11 en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,dir); //Escribe Direc. en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,dato); //Escribe Dato en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo error=sub3100(); //Espera a que el emulador escriba if (error) return(error); //Si ha expirado el tiempo com.dl=inportb(PORTA); //Captura PORTA, restaura IBF a 0. if (!((dir==0xB8)||(dir==0xA8)||(dir==0xA0)\ ||(dir==0x99)||(dir==0x80)||(dir==0x87))){ if (com.dl!=dato){ //Si dato_recibido!=dato_enviado error=1; return(error); } } outportb(PORTA,0x00); //Escribe 00h en PORTA,!OBF=0 error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo return(0); } /*************************************************************** INT SERVICIO14 (U_CHAR DIR_H, U_CHAR DIR_L, U_CHAR RUPT_H, U_CHAR RUPT_L); "Ejecucion del Codigo con Punto de Ruptura (1ra Parte)" **************************************************************/ int servicio14 (u_char dir_h, u_char dir_l, u_char rupt_h, u_char rupt_l){ int error; error=0; outportb(PORTA,0xFF); //Escribe FFh en PORTA,!OBF=0 error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(1); 213 ITF51 if (error) return(error); //Si ha expirado el tiempo outportb(PORTA,0x0E); //Escribe servicio14 en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea if (error) return(error); //Si ha expirado el tiempo retardo(3); outportb(PORTA,dir_h); //Escribe Dir_H en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea retardo(3); outportb(PORTA,dir_l); //Escribe Dir_L en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea outportb(PORTA,rupt_h); //Escribe Rupt_H en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea outportb(PORTA,rupt_l); //Escribe Rupt_L en PORTA,!OBF=0 error=sub3140(); //Espera a que el emulador lea error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo error=sub3320(2); if (error) return(error); //Si ha expirado el tiempo return(0); } /*************************************************************** INT SERVICIO15 (VOID); "Ejecucion del Codigo con Punto de Ruptura (2da Parte)" **************************************************************/ int servicio15 (void){ int error; error=0; error=sub3320(1); if (error) return(error); //Si ha expirado el tiempo return(0); } /*-------------------------------------------VOID RETARDO (INT TICS); Funcion que paraliza el programa principal durante tics/18 segundos. (Las interrupciones siguen activas). ----------------------------------------------*/ void retardo (int tics){ st.count=tics; //Cargamos el contador a tics st.fin=0; //Encendemos el contador while (!st.fin); 214 ITF51 } /*-------------------------------------------VOID CONVERSOR (CHAR VALOR) Funcion que representa en el cuadro conversor el valor en decimal, hexadecimal y binario. ----------------------------------------------*/ void conversor (char valor){ escribir_dec (8,43,valor); escribir_hex (8,45,valor,0); escribir_bin (8,47,valor); } /*--------------------------------------------------------------INT LISTADO (int PC); Lista el programa a partir de la posicion indicada por el contador de programa (PC) Linea correcta: 18 0027 7A A0 MOV R2,#A0H ------------------------------------------------------------------*/ int listado (int PC, char activo){ FILE *lst; //Archivo de listado *.LST char alfa[4]; //Los 4 caracteres que en el //listado nos indican la //posicion de memoria int i,espacio,espacio2,posicion,fila,eof,linea_ok; //I: variable de ayuda //Espacio:=1 linea sin instruccion // =2 linea con END //Espacio2:linea sin instrucciones //Posicion:bytes a rebobinar en caso // de ser una linea buena //Fila:de 4 a 36. Direccion Y //Eof:=3 si se ha leido "END" //Linea_ok:linea actual correcta char iluminada,caracter; //Iluminada:primera linea con // instruccion iluminada //Caracter:dato leido del *.LST alfa[0]=alfa[1]=alfa[2]=alfa[3]=0; fila=4; iluminada=0; 215 ITF51 espacio=posicion=eof=0; linea_ok=1; rectangulo (20,4,60,36,3,atributo); escribir_palabra (29,2," //Limpiamos el cuadro principal LISTADO ",atributo); lst=fopen(ficheroLST,"r"); //Abrimos el fichero de listado i=0; //Empezamos buscando en el archivo de listado la direccion de //PC deseada. Una vez encontrada, situamos el puntero del //archivo en esa linea. while (i<12){ if (i==8) alfa[0]=caracter; //Los 4 caracteres else if (i==9) alfa[1]=caracter; //que pueden contener else if (i==10) alfa[2]=caracter; //la direccion de else if (i==11) alfa[3]=caracter; //PC deseada i++; caracter=fgetc(lst); //Adquirimos caracter del fichero //incrementando el puntero en 1 } a4toh(alfa); //Convertimos los 4 caracteres en //el entero list.direccion while ((PC!=list.direccion)&&(caracter!=EOF)){ //Comparamos el PC deseado con el //valor obtenido, mientras no estemos //al final del fichero i=0; caracter=fgetc(lst); //Adquirimos caracter del fichero //incrementando el puntero en 1 while ((i<12)&&(caracter!=0x0A)&&(caracter!=EOF)){ if (i==8) alfa[0]=caracter; //Los 4 caracteres que else if (i==9) alfa[1]=caracter; //pueden contener else if (i==10) alfa[2]=caracter; //la direccion deseada else if (i==11) { alfa[3]=caracter; a4toh(alfa); //Nuevo list.direccion } i++; caracter=fgetc(lst); //Adquirimos caracter del fichero //incrementando el puntero en 1 } if (PC==list.direccion) fseek(lst,-i-1,1); //Si hemos encontrado el PC //Retrocedemos hasta el principio //de la linea 216 ITF51 else if ((PC!=list.direccion)&&(i==12)){ //Si PC erroneo while ((caracter!=0x0A)&&(caracter!=EOF)){ //Terminamos de leer la linea caracter=fgetc(lst); //Adquirimos caracter del fichero //incrementando el puntero en 1 } } } if (caracter==EOF){ //Si hemos llegado al final del PC--; //fichero (no se ha encontrado rewind(lst); //el PC) rebobinamos *.LST y caracter=0; //decrementamos el PC en 1 } list.direccion=0; //Repeticion de la busqueda del PC. Si no se encontro antes, esta vez //se hara con PC=PC-1. Si se encontro, ahora se obtiene lo mismo. while ((PC!=list.direccion)&&(caracter!=EOF)){ i=0; caracter=fgetc(lst); while ((i<12)&&(caracter!=0x0A)&&(caracter!=EOF)){ if (i==8) alfa[0]=caracter; else if (i==9) alfa[1]=caracter; else if (i==10) alfa[2]=caracter; else if (i==11) { alfa[3]=caracter; a4toh(alfa); } i++; caracter=fgetc(lst); } if (PC==list.direccion) fseek(lst,-i-1,1); else if ((PC!=list.direccion)&&(i==12)){ while ((caracter!=0x0A)&&(caracter!=EOF)){ caracter=fgetc(lst); } } } if (caracter==EOF){ PC--; rewind(lst); caracter=0; } list.direccion=0; //Repeticion de la busqueda del PC. Si no se encontro las 2 veces 217 ITF51 //anteriores, esta vez se hara con PC=PC-2. Si se encontro anteriormente, //ahora se obtiene lo mismo. while ((PC!=list.direccion)&&(caracter!=EOF)){ i=0; caracter=fgetc(lst); while ((i<12)&&(caracter!=0x0A)&&(caracter!=EOF)){ if (i==8) alfa[0]=caracter; else if (i==9) alfa[1]=caracter; else if (i==10) alfa[2]=caracter; else if (i==11) { alfa[3]=caracter; a4toh(alfa); } i++; caracter=fgetc(lst); } if (PC==list.direccion) fseek(lst,-i-1,1); else if ((PC!=list.direccion)&&(i==12)){ while ((caracter!=0x0A)&&(caracter!=EOF)){ caracter=fgetc(lst); } } } if (caracter==EOF) return(1); //Si no se ha encontrado //PC ni PC-1 ni PC-2: Error //Aqui ya estamos en la linea del *.LST adecuada. Empezamos a //comprovar todas las siguientes lineas. Si son correctas las escribimos //hasta llenar el cuadro principal while ((fila<=36)&&(eof!=3)){ //Mientras no este lleno el cuadro //principal y no se lea "END" posicion=0; i=0; while ((i<5)&&(caracter!=0x0A)){ //5 primeros caracteres y caracter=fgetc(lst); //no "fin de linea" posicion++; //Incrementamos x de la linea if (caracter==0x3B) linea_ok=0; //Si ";" i++; } if (caracter==0x0A) linea_ok=0; //Si "fin de linea" else if (caracter!=0x0A){ //Si no "fin de linea" if (!((caracter>=48)&&(caracter<=57))) linea_ok=0;//Si el caracter no i=0; //es una cifra entre el 0 y 9 while ((i<3)&&(caracter!=0x0A)){ //3 siguientes caracteres y 218 ITF51 caracter=fgetc(lst); //no "fin de linea" posicion++; //Incrementamos x de la linea if (caracter!=0x20) linea_ok=0; //Si no "espacio en blanco" i++; } if (caracter==0x0A){ linea_ok=0; //Si "fin de linea" } else if (caracter!=0x0A){ //Si no "fin de linea" i=0; while ((i<4)&&(caracter!=0x0A)){ //4 siguientes caracteres y caracter=fgetc(lst); //no "fin de linea" posicion++; //Incrementamos x de la linea if (!(((caracter>=48)&&(caracter<=57))||((caracter>=65)\ &&(caracter<=70)))) linea_ok=0; //Si el caracter no i++; //esta en hexadecimal } } } if (!linea_ok); //Si la linea no es correcta else if (linea_ok){ //Si la linea es correcta fseek (lst,(-posicion+8),1); //Retrocedemos desde la posicion i=0; //actual hasta el principio while (i<4){ //5 primeros caracteres caracter=fgetc(lst); escribir_car (20+i,fila,caracter,atributo);//Representacion en pantalla i++; } i=0; while (i<12){ //Siguientes 12 caracteres caracter=fgetc(lst); escribir_car (24+i,fila,caracter,atributo);//Representacion en pantalla if (i==3){ //1er caracter de direccion PC if (caracter==0x20) espacio=1; //Si "espacio en blanco" } i++; } i=0; while ((caracter==0x20)||(caracter==0x09)){//Avanzar el puntero del caracter=fgetc(lst); //archivo hasta un caracter i++; } if ((i>12)&&(espacio)) espacio=2; //Si no es una etiqueta if (espacio){ 219 ITF51 espacio2=espacio; //Actualizamos espacio2 i=0; while ((caracter!=0x0A)&&(caracter!=0x3B)){//Mientras no "final de //linea" y no ";" if (espacio==1) escribir_car (38+i,fila,caracter,atributo); //Representar toda la linea if (espacio==2) { escribir_car (42+i,fila,caracter,atributo); if ((caracter==69)&&(eof==0)) eof=1; //Buscamos la else if ((caracter==78)&&(eof==1)) eof=2;//cadena de else if ((caracter==68)&&(eof==2)) eof=3;//caracteres "END" } caracter=fgetc(lst); i++; } if (caracter==0x3B){ //Si caracter=";" while (caracter!=0x0A){ //Mientras caracter=fgetc(lst); no "fin de linea" //preparamos el puntero para } //la siguiente linea } espacio=0; //Restaurar espacio } else if (!espacio){ //Si la linea contiene instruccion espacio2=espacio; //Actualizar espacio2 i=0; while ((caracter!=0x0A)&&(caracter!=0x3B)){//Mientras no "fin de linea" escribir_car (42+i,fila,caracter,atributo);//y no ";" representamos caracter=fgetc(lst); //la linea en el cuadro secundario i++; } if (caracter==0x3B){ //Si caracter=";" while (caracter!=0x0A){ //Mientras caracter=fgetc(lst); no "fin de linea" //preparamos el puntero para } //la siguiente linea } } //Si la linea contiene alguna instruccion, y activo=1 y aun no se ha //iluminado ninguna linea: if ((!espacio2)&&(!iluminada)&&(activo)){ for(i=20;i<=60;i++){ cambiar_atributo (i,fila,atributo_inverso);//Cambiamos el atributo } //de toda la linea iluminada++; //Indicamos que ya hemos 220 ITF51 } //activado una linea fila++; } caracter=0x00; //Restaurar variables linea_ok=1; posicion=0; } fclose(lst); //Cerrar "fichero".LST return(0); } /*-----------------------------------------------------------void A4TOH(char alfa[4]); Toma una cadena de 4 caracteres como un numero en hexadecimal y lo convierte a un entero. ------------------------------------------------------------*/ void a4toh(char aalfa[4]){ int tmp1,tmp2; //Variables de ayuda int i; tmp1=tmp2=0; for(i=0;i<4;i++){ if (aalfa[i]==48) tmp1=0; else if (aalfa[i]==49) tmp1=1; else if (aalfa[i]==50) tmp1=2; else if (aalfa[i]==51) tmp1=3; else if (aalfa[i]==52) tmp1=4; else if (aalfa[i]==53) tmp1=5; else if (aalfa[i]==54) tmp1=6; else if (aalfa[i]==55) tmp1=7; else if (aalfa[i]==56) tmp1=8; else if (aalfa[i]==57) tmp1=9; else if (aalfa[i]==65) tmp1=10; else if (aalfa[i]==66) tmp1=11; else if (aalfa[i]==67) tmp1=12; else if (aalfa[i]==68) tmp1=13; else if (aalfa[i]==69) tmp1=14; else if (aalfa[i]==70) tmp1=15; if (i==0) tmp2=tmp2+(tmp1<<12); else if (i==1) tmp2=tmp2+(tmp1<<8); else if (i==2) tmp2=tmp2+(tmp1<<4); else if (i==3) tmp2=tmp2+tmp1; 221 ITF51 } list.direccion=tmp2; //Devuelve el resultado } //a list.direccion /********************************************************* VOID ENCONTRAR_SIZE (FILE *ORIGINAL, U_INT *CONST SIZE_H,\ U_INT *CONST SIZE_L); Funcion que dado un fichero devuelve su tama¤o, expresado en 2 bytes (size_h,size_l). **********************************************************/ void encontrar_size (FILE *original, u_int *const size_h, u_int *const size_l){ u_int temp1; //Variable de ayuda temp1=0; rewind(original); //Rebobinamos fichero while (!feof(original)){ //Mientras no "fin de fichero" getc(original); //Recorremos todo el fichero temp1++; } temp1--; *size_l=temp1&0x00FF; //Devolvemos el byte bajo *size_h=temp1>>8; //Devolvemos el byte alto rewind(original); //Rebobinamos fichero } /****************************************************** VOID GESTION_PAUSA (U_INT CODIGO); Dentro del servicio a la interrupcion del teclado gestiona las acciones que hacer al volver de la pausa. ******************************************************/ void gestion_pausa (u_int codigo){ u_int temp1,temp2; temp1=temp2=0; if (codigo==ENTER){ //Solo volvemos de la pausa //si el codigo pulsado es ENTER rectangulo (20,40,60,47,3,atributo); //Limpiar cuadro secundario if ((cursor.color>0)&&(cursor.color<23)){ //Menu de escojer el color representar_color (cursor.color); } if (cursor.color==23){ //Volvemos de escojer unos colores atributo=funcion.dpl; //Tendremos que redibujar toda atributo_inverso=funcion.dph; //la pantalla tal y como estaba for(temp2=0;temp2<50;temp2++){ 222 ITF51 for(temp1=0;temp1<80;temp1++){ cambiar_atributo (temp1,temp2,atributo); } } representar_punto_ruptura(); representar_estado (SW1&0x02); cursor.color=0; cursor.principal=52; escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,32,"Color",atributo_inverso); } if (cursor.principal==41){ //Activar punto de ruptura representar_punto_ruptura(); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,26,"Activar",atributo_inverso); } if (cursor.principal==13){ //Resetear programa escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,9,"Resetear",atributo_inverso); } if ((cursor.principal==22)){ escribir_palabra (2,2," //Transferir programa y M E N U ",atributo_inverso); escribir_palabra (5,15,"Transferir",atributo_inverso); } if ((cursor.principal>=15)&&(cursor.principal<=18)){ //Menu ejecutar - menu paso a paso representar_registros_dinamico(0); representar_ejecutar(cursor.principal-14); } if (cursor.principal==32){ //Listar registros representar_registros_dinamico(0); escribir_palabra (2,2," M E N U ",atributo_inverso); escribir_palabra (5,21,"Listar",atributo_inverso); } if (cursor.pag_programa){ //Volver de escribir un byte en mem_prog representar_memoria_estatico (1,1); } if (cursor.pag_datos){ //Volver de escribir un byte en mem_dat representar_memoria_estatico (1,2); } if (cursor.pag_interna){ //Volver de escribir un byte en mem_int representar_memoria_estatico (1,3); } 223 ITF51 if (cursor.registros) representar_registros_estatico (cursor.registros); //Volver de escribir un registro SW1=SW1&0xFE; //pausa desactivada } } Código 4. ITF51.C 224 ITF51 5.3.2 Listado del Programa para el Microcontrolador 8051 2500 A.D. 8051 CROSS ASSEMBLER - VERSION 3.41f -------------------------------------------------- INPUT FILENAME : MODIFI.ASM OUTPUT FILENAME : MODIFI.OBJ 1 8000 2 8000 90 80 03 ORG 8000H MOV DPTR,#8003H 3 8003 74 02 MOV A,#2 4 8005 F0 MOVX @DPTR,A 5 8006 A3 INC DPTR 6 8007 74 80 MOV A,#80H 7 8009 F0 MOVX @DPTR,A 8 800A A3 INC DPTR 9 800B 74 30 MOV A,#30H 10 800D F0 MOVX @DPTR,A 11 800E 75 A8 E1 MOV IE,#E1H 12 8011 90 9F FE MOV DPTR,#9FFEH 13 8014 74 80 MOV A,#80H 14 8016 F0 MOVX @DPTR,A 15 8017 A3 INC DPTR 16 8018 74 FE MOV A,#FEH 17 801A F0 MOVX @DPTR,A 18 801B E4 CLR A 19 801C 75 83 00 MOV DPH,#0 20 801F 75 82 00 MOV DPL,#0 21 8022 02 9F FE LJMP ULTIMA 22 ;VA A ENTRETENIMIENTO ;PROGRAMA DEBUG 23 24 ;PENULTIMA DIRECCION CHIP 8 Kb ; 8030 ORG 8030H 25 ; 26 ;SALVAR REGISTROS AFECTADOS 27 ; 28 8030 C0 E0 PUSH A 29 8032 C0 82 PUSH DPL 30 8034 C0 83 PUSH DPH 31 8036 90 C0 00 MOV DPTR,#C000H 32 8039 E0 MOVX A,@DPTR 33 803A D0 83 POP DPH 34 803C D0 82 POP DPL 35 803E 12 82 AE LCALL AVISO 225 ;DATA/CODE ITF51 36 8041 D0 E0 POP A 37 8043 C0 82 PUSH DPL 38 8045 C0 83 PUSH DPH 39 8047 90 1F E0 MOV DPTR,#1FE0H ;PARTE ALTA CHIP 2K 40 804A F0 MOVX @DPTR,A ;SALVAR ACC 41 804B E5 F0 MOV A,B 42 804D A3 INC DPTR 43 804E F0 MOVX @DPTR,A 44 804F E5 D0 MOV A,PSW 45 8051 A3 INC DPTR 46 8052 F0 MOVX @DPTR,A 47 8053 88 F0 MOV B,R0 48 8055 E5 81 MOV A,SP 49 8057 F8 MOV R0,A 50 8058 E6 MOV A,@R0 51 8059 A3 INC DPTR 52 805A F0 MOVX @DPTR,A 53 805B 18 DEC R0 54 805C 15 81 DEC SP 55 805E E6 MOV A,@R0 56 805F A3 INC DPTR 57 8060 F0 MOVX @DPTR,A 58 8061 18 DEC R0 59 8062 15 81 DEC SP 60 8064 E6 MOV A,@R0 61 8065 A3 INC DPTR 62 8066 F0 MOVX @DPTR,A 63 8067 18 DEC R0 64 8068 15 81 DEC SP 65 806A E6 MOV A,@R0 66 806B A3 INC DPTR 67 806C F0 MOVX @DPTR,A 68 806D 15 81 DEC SP 69 806F E5 81 MOV A,SP 70 8071 A3 INC DPTR 71 8072 F0 MOVX @DPTR,A 72 8073 E5 F0 MOV A,B 73 8075 A3 INC DPTR 74 8076 F0 MOVX @DPTR,A 75 8077 E9 MOV A,R1 76 8078 05 82 INC DPL 77 807A F0 MOVX @DPTR,A 78 807B EA MOV A,R2 79 807C 05 82 INC DPL 80 807E F0 MOVX @DPTR,A 81 807F EB MOV A,R3 226 ;SALVAR B ;SALVAR PSW ;SALVAR DPH ;SALVAR DPL ;SALVAR PCH ;SALVAR PCL ;SALVAR SP ;SALVAR R0 ;SALVAR R1 ;SALVAR R2 ITF51 82 8080 05 82 INC DPL 83 8082 F0 MOVX @DPTR,A 84 8083 EC MOV A,R4 85 8084 05 82 INC DPL 86 8086 F0 MOVX @DPTR,A 87 8087 ED MOV A,R5 88 8088 05 82 INC DPL 89 808A F0 MOVX @DPTR,A 90 808B EE MOV A,R6 91 808C 05 82 INC DPL ;SALVAR R3 ;SALVAR R4 ;SALVAR R5 92 808E F0 MOVX @DPTR,A 93 808F EF MOV A,R7 94 8090 05 82 INC DPL 95 8092 F0 MOVX @DPTR,A ;SALVAR R7 96 8093 12 82 AE LCALL AVISO ;DATA/CODE 97 ; 98 ;ATENDER SERVICIO SOLICITADO 99 ; 100 8096 20 B2 FD 101 8099 90 C0 00 MOV DPTR,#C000H 102 809C E0 MOVX A,@DPTR 103 809D B4 0E 03 CJNE A,#0EH,D0 104 80A0 02 86 21 LJMP CATORCE 105 80A3 B4 00 03 106 80A6 02 81 76 107 80A9 B4 01 03 108 80AC 02 82 11 109 80AF B4 02 03 110 80B2 02 81 92 111 80B5 B4 03 03 112 80B8 02 81 DE 113 80BB B4 04 03 114 80BE 02 82 34 115 80C1 B4 05 03 116 80C4 02 82 C2 117 80C7 B4 06 03 118 80CA 02 82 DB 119 80CD B4 07 03 120 80D0 02 83 C7 121 80D3 B4 08 03 122 80D6 02 83 E1 123 80D9 B4 09 03 124 80DC 02 84 04 125 80DF B4 0A 03 126 80E2 02 84 71 127 80E5 B4 0B 03 DFF D0 JB P3.2,DFF CJNE A,#0,D1 LJMP CERO D1 CJNE A,#01H,D2 LJMP UNO D2 CJNE A,#02H,D3 LJMP DOS D3 CJNE A,#03H,D4 LJMP TRES D4 CJNE A,#04H,D5 LJMP CUAT D5 CJNE A,#05H,D6 LJMP CINC D6 CJNE A,#06H,D7 LJMP SEIS D7 CJNE A,#07H,D8 LJMP SIETE D8 CJNE A,#08H,D9 LJMP OCHO D9 ;SALVAR R6 CJNE A,#09H,D10 LJMP NUEVE D10 CJNE A,#0AH,D11 D11 CJNE A,#0BH,D12 LJMP DIEZ 227 ;PASO PASO ITF51 128 80E8 02 84 8B 129 80EB B4 0C 03 130 80EE 02 86 15 131 80F1 B4 0D 03 132 80F4 02 81 65 LJMP ONCE D12 CJNE A,#0CH,D13 LJMP DOCE D13 CJNE A,#0DH,SALIR LJMP TRECE 133 ; 134 ;RECUPERAR REGISTROS SALVADOS 135 ; 136 80F7 137 80F7 SALIR: 51 AE ACALL AVISO ;DATA/CODE 138 80F9 90 1F E0 MOV DPTR,#1FE0H ;ORIGEN STACK 139 80FC 74 0F MOV A,#0FH ;FIN STACK 140 80FE 93 MOVC A,@A+DPTR ;POP R7 141 80FF FF MOV R7,A 142 8100 74 0E MOV A,#EH 143 8102 93 MOVC A,@A+DPTR 144 8103 FE MOV R6,A 145 8104 74 0D MOV A,#DH 146 8106 93 MOVC A,@A+DPTR 147 8107 FD MOV R5,A 148 8108 74 0C MOV A,#CH 149 810A 93 MOVC A,@A+DPTR 150 810B FC MOV R4,A 151 810C 74 0B MOV A,#BH 152 810E 93 MOVC A,@A+DPTR 153 810F FB MOV R3,A 154 8110 74 0A MOV A,#AH 155 8112 93 MOVC A,@A+DPTR 156 8113 FA MOV R2,A 157 8114 74 09 MOV A,#9 158 8116 93 MOVC A,@A+DPTR 159 8117 F9 MOV R1,A 160 8118 74 08 MOV A,#8 161 811A 93 MOVC A,@A+DPTR 162 811B F8 MOV R0,A 163 ;POP R6 ;POP R5 ;POP R4 ;POP R3 ;POP R2 ;POP R1 ;POP R0 ; 164 811C 74 07 MOV A,#7 165 811E 93 MOVC A,@A+DPTR 166 811F F5 81 MOV SP,A 167 ;POP SP ; 168 8121 74 06 MOV A,#6 169 8123 93 MOVC A,@A+DPTR 170 8124 C0 E0 PUSH A 171 ;POP PCL ; 172 8126 74 05 MOV A,#5 173 8128 93 MOVC A,@A+DPTR 228 ;POP PCH ITF51 174 8129 C0 E0 176 812B 74 04 MOV A,#4 177 812D 93 MOVC A,@A+DPTR 178 812E C0 E0 PUSH A 175 PUSH A ; 179 ; 180 8130 74 03 MOV A,#3 181 8132 93 MOVC A,@A+DPTR 182 8133 C0 E0 PUSH A 183 184 8135 74 01 MOV A,#1 8137 93 MOVC A,@A+DPTR 186 8138 F5 F0 MOV B,A 187 ;B ; 188 813A 74 02 MOV A,#2 189 813C 93 MOVC A,@A+DPTR 190 813D C0 E0 PUSH A 191 ;POP PSW ; 192 813F E4 CLR A 193 8140 93 MOVC A,@A+DPTR 194 ;POP ACC ; 195 8141 50 09 JNC SALIR_1 196 8143 90 C0 01 MOV DPTR,#C001H 197 8146 F0 198 8147 20 B2 FD 199 814A 80 12 200 MOVX @DPTR,A SAL ;AVISO DATA/CODE JB P3.2,SAL SJMP SALIR_2 ; 201 814C 202 814C 30 D5 0F JNB PSW.5,SALIR_2 203 814F 90 C0 01 MOV DPTR,#C001H 204 8152 F0 MOVX @DPTR,A 205 8153 20 B2 FD 206 8156 C0 E0 PUSH A 207 8158 75 82 00 MOV DPL,#0 208 815B E0 MOVX A,@DPTR 209 815C D0 E0 POP A 210 815E 211 815E D0 D0 POP PSW 212 8160 D0 83 POP DPH 213 8162 D0 82 POP DPL SALIR_1: 214 8164 32 SAL1 JB P3.2,SAL1 SALIR_2: RETI 215 ; 216 ;RUTINA DE ENTRETENIMIENTO 217 ; 219 ;POP DPH ; 185 218 ;POP DPL 8165 TRECE: ; 229 ;AVISO DATA/CODE ITF51 220 8165 90 1F E5 MOV DPTR,#1FE5H 221 8168 74 80 MOV A,#80H 222 816A F0 MOVX @DPTR,A 223 816B 05 82 INC DPL 224 816D 74 22 MOV A,#22H 225 816F F0 MOVX @DPTR,A 226 8170 C3 CLR C 227 8171 C2 D5 CLR PSW.5 228 8173 02 80 F7 LJMP SALIR 229 ; 230 ;RUTINA DE INICIALIZACION 231 ; 232 8176 233 8176 90 1F E5 MOV DPTR,#1FE5H 234 8179 74 80 MOV A,#80H 235 817B F0 MOVX @DPTR,A 236 817C 75 82 F0 MOV DPL,#F0H 237 817F E4 CLR A ;ACTUALIZAR PCH ;ACTUALIZAR PCL CERO: 238 8180 F0 MOVX @DPTR,A 239 8181 75 82 E6 MOV DPL,#E6H 240 8184 74 22 MOV A,#22H 241 8186 F0 MOVX @DPTR,A 242 8187 75 82 F1 MOV DPL,#F1H ;PCH=80h ;COPIA=0 ;PCL=22h 243 818A E4 CLR A 244 818B F0 MOVX @DPTR,A ;COPIA=0 245 818C C3 CLR C ;NO "T" 246 818D C2 D5 CLR PSW.5 ;NO "G" 247 818F 02 80 F7 LJMP SALIR 248 ; 249 ; 250 ; 251 ;RUTINA DE TRANSFERENCIA DE PC A 8031, "W XXXX XXXX" 252 ; 253 8192 20 B2 FD DOS JB P3.2,DOS ;AQUI SE RECIBE DIREC ORIGEN Y FIN 254 8195 90 C0 00 MOV DPTR,#C000H 255 8198 E0 MOVX A,@DPTR 256 8199 C0 E0 257 819B 20 B2 FD 258 819E E0 MOVX A,@DPTR 259 819F C0 E0 PUSH A 260 81A1 20 B2 FD 261 81A4 E0 MOVX A,@DPTR 262 81A5 FF MOV R7,A 263 81A6 20 B2 FD 264 81A9 E0 MOVX A,@DPTR 265 81AA FE MOV R6,A PUSH A X1 X2 X3 JB P3.2,X1 JB P3.2,X2 JB P3.2,X3 230 ITF51 266 ; 267 ;AQUI SE RECIBEN LOS BYTES A SER ESCRITOS 268 ; 269 81AB 20 B2 FD X20 JB P3.2,X20 270 81AE 90 C0 00 MOV DPTR,#C000H 271 81B1 E0 MOVX A,@DPTR 272 81B2 D0 82 POP DPL 273 81B4 D0 83 POP DPH 274 81B6 F0 MOVX @DPTR,A 275 81B7 E0 MOVX A,@DPTR 276 81B8 51 9A ACALL REC 277 81BA E5 83 MOV A,DPH 278 81BC 6F XRL A,R7 279 81BD 70 18 JNZ X21 ;VERIFICACION 280 81BF E5 82 MOV A,DPL 281 81C1 6E XRL A,R6 282 81C2 70 13 JNZ X21 283 81C4 51 AE ACALL AVISO ;DATA/CODE 285 81C6 90 1F E5 MOV DPTR,#1FE5H ;PCH 286 81C9 74 80 MOV A,#80H 287 81CB F0 MOVX @DPTR,A 288 81CC 05 82 INC DPL 289 81CE 74 22 MOV A,#22H 290 81D0 F0 MOVX @DPTR,A ;PC=ENTRETENIMIENTO 8022h 291 81D1 C3 CLR C ;NO "T" 292 81D2 C2 D5 CLR PSW.5 ;NO "G" 293 81D4 02 80 F7 294 81D7 295 81D7 A3 INC DPTR 296 81D8 C0 83 PUSH DPH 284 ; LJMP SALIR X21: 297 81DA C0 82 PUSH DPL 298 81DC 80 CD SJMP X20 299 ; 300 ;RUTINA DE TRANF. 8031 TO PC "D XXXX XXXX" 301 ; 302 303 81DE TRES:;AQUI SE RECIBEN LAS DIRECCIONES DE ORIGEN Y FIN 304 81DE 20 B2 FD JB P3.2,TRES 305 81E1 90 C0 00 MOV DPTR,#C000H 306 81E4 E0 MOVX A,@DPTR 307 81E5 C0 E0 PUSH A 308 81E7 20 B2 FD 309 81EA E0 310 81EB C0 E0 311 81ED 20 B2 FD Y30 JB P3.2,Y30 MOVX A,@DPTR PUSH A Y31 JB P3.2,Y31 231 ITF51 312 81F0 E0 MOVX A,@DPTR 313 81F1 FF 314 81F2 20 B2 FD MOV R7,A 315 81F5 E0 MOVX A,@DPTR 316 81F6 FE MOV R6,A Y32 JB P3.2,Y32 317 ; 318 ;AQUI SE TRANSFIEREN LOS DATOS AL PC 319 ; 320 81F7 D0 82 POP DPL 321 81F9 D0 83 POP DPH 322 81FB E0 323 81FC 51 9A ACALL REC 324 81FE E5 83 MOV A,DPH 325 8200 6F XRL A,R7 326 8201 70 0B JNZ X33 327 8203 E5 82 MOV A,DPL 328 8205 6E XRL A,R6 329 8206 70 06 JNZ X33 X32 MOVX A,@DPTR 330 8208 C3 CLR C ;NO "T" 331 8209 C2 D5 CLR PSW.5 ;NO "G" 332 820B 02 80 F7 LJMP SALIR 333 820E A3 334 820F 80 EA X33 INC DPTR SJMP X32 335 ; 336 ;RUTINA DE EJECUCION PASO A PASO "T XXXX" 337 ; 338 ;INICIALIZACION 339 ; 340 8211 20 B2 FD UNO JB P3.2,UNO 341 8214 90 C0 00 MOV DPTR,#C000H 342 8217 E0 MOVX A,@DPTR 343 8218 FF 344 8219 20 B2 FD MOV R7,A 345 821C E0 MOVX A,@DPTR 346 821D 90 1F E5 MOV DPTR,#1FE5H ;POSICION DE PCH 347 8220 F0 MOVX @DPTR,A ;PUSH PCH 348 8221 75 82 F0 MOV DPL,#F0H 349 8224 F0 MOVX @DPTR,A 350 8225 EF MOV A,R7 351 8226 75 82 E6 MOV DPL,#E6H X10 JB P3.2,X10 ;DUPLICAR PCH 352 8229 F0 MOVX @DPTR,A 353 822A 75 82 F1 MOV DPL,#F1H 354 822D F0 MOVX @DPTR,A ;DUPLICAR PCL 355 822E D3 SETB C ;SI "T" 356 822F C2 D5 CLR PSW.5 ;NO "G" 357 8231 02 80 F7 LJMP SALIR 232 ;PUSH PCL ITF51 358 ; 359 ;SE TRANSFIEREN REGISTROS INTERNOS AL PC 360 ; 361 8234 CUAT: 362 8234 90 1F E0 MOV DPTR,#1FE0H 363 8237 74 03 MOV A,#3 364 8239 93 MOVC A,@A+DPTR 365 823A 51 9A ACALL REC 366 823C 74 04 MOV A,#4 367 823E 93 MOVC A,@A+DPTR 368 823F 51 9A ACALL REC 369 8241 74 0F MOV A,#0FH 370 8243 371 8243 ;DPH ;DPL REG3: F5 F0 MOV B,A 372 8245 93 MOVC A,@A+DPTR 373 8246 51 9A ACALL REC 374 8248 E5 F0 MOV A,B 375 824A 14 DEC A 376 824B B4 07 F5 377 ;R7 a R0 CJNE A,#7,REG3 ; 378 824E 74 01 MOV A,#1 379 8250 93 MOVC A,@A+DPTR 380 8251 51 9A ACALL REC 382 8253 74 02 MOV A,#2 383 8255 93 MOVC A,@A+DPTR 384 8256 51 9A ACALL REC 386 8258 74 05 MOV A,#5 387 825A 93 MOVC A,@A+DPTR 388 825B FF MOV R7,A 389 825C 51 9A 381 ;B ; 385 ;PSW ; 390 ACALL REC ;PCH ; 391 825E 74 06 MOV A,#6 392 8260 93 MOVC A,@A+DPTR 393 8261 FE MOV R6,A 394 8262 51 9A 395 ACALL REC ;PCL ; 396 8264 74 07 MOV A,#7 397 8266 93 MOVC A,@A+DPTR 398 8267 51 9A 399 ACALL REC ; 400 8269 EF MOV A,R7 401 826A F5 83 MOV DPH,A 402 826C EE MOV A,R6 403 826D F5 82 MOV DPL,A 233 ;SP ITF51 404 826F E4 CLR A 405 8270 93 MOVC A,@A+DPTR 406 8271 51 9A ACALL REC 407 8273 74 01 MOV A,#1 408 8275 93 MOVC A,@A+DPTR 409 8276 51 9A ACALL REC 410 8278 74 02 MOV A,#2 411 827A 93 MOVC A,@A+DPTR 412 827B 51 9A ACALL REC 413 ;BYTE n' 1 DE INSTRUCCION ;BYTE n' 2 DE INSTRUCCION ;BYTE n' 3 DE INSTRUCCION ; 414 827D 90 1F E0 MOV DPTR,#1FE0H 415 8280 E4 CLR A 416 8281 93 MOVC A,@A+DPTR 417 8282 51 9A ACALL REC 418 ; 419 ;DUPLICAR PROGRAM COUNTER 420 ; ;ACC 421 8284 90 1F E5 MOV DPTR,#1FE5H 422 8287 E0 MOVX A,@DPTR 423 8288 75 82 F0 MOV DPL,#F0H 424 828B F0 MOVX @DPTR,A 425 828C 75 82 E6 MOV DPL,#E6H 426 828F E0 MOVX A,@DPTR 427 8290 75 82 F1 MOV DPL,#F1H 428 8293 F0 MOVX @DPTR,A 429 8294 D3 SETB C ;SI "T" 430 8295 C2 D5 CLR PSW.5 ;NO "G" 431 8297 02 80 F7 432 LJMP SALIR ; 433 829A C0 82 434 829C C0 83 PUSH DPH 435 829E 90 C0 01 MOV DPTR,#C001H 436 82A1 F0 MOVX @DPTR,A 437 82A2 20 B2 FD 438 82A5 90 C0 00 MOV DPTR,#C000H 439 82A8 E0 MOVX A,@DPTR 440 82A9 D0 83 POP DPH 441 82AB D0 82 POP DPL 442 82AD 22 RET 443 REC X42 PUSH DPL JB P3.2,X42 ; 444 ;RUTINA PARA AVISO DE ACCESO CODIGO O DATOS 445 82AE AVISO: 446 82AE C0 82 PUSH DPL 447 82B0 C0 83 PUSH DPH 448 82B2 90 C0 01 MOV DPTR,#C001H 449 82B5 F0 MOVX @DPTR,A 234 ITF51 450 82B6 20 B2 FD X43 JB P3.2,X43 451 82B9 75 82 00 MOV DPL,#0 452 82BC E0 MOVX A,@DPTR 453 82BD D0 83 POP DPH 454 82BF D0 82 POP DPL 455 82C1 22 RET 456 ; 457 ;RUTINA DE EJECUCION "G XXXX" 458 ; 459 82C2 20 B2 FD CINC 460 82C5 90 C0 00 MOV DPTR,#C000H 461 82C8 E0 MOVX A,@DPTR 462 82C9 FF MOV R7,A 463 82CA 20 B2 FD 464 82CD E0 MOVX A,@DPTR 465 82CE 90 1F E5 MOV DPTR,#1FE5H ;APUNTA A PCH 466 82D1 F0 MOVX @DPTR,A ;PUSH PCH 467 82D2 A3 INC DPTR X50 JB P3.2,CINC JB P3.2,X50 468 82D3 EF MOV A,R7 469 82D4 F0 MOVX @DPTR,A ;PCL 470 82D5 D2 D5 SETB PSW.5 ;SI "G" 471 82D7 C3 CLR C ;NO "T" 472 82D8 02 80 F7 LJMP SALIR 473 ; 474 ;RUTINA DE TRANF. DE RAM INTERNA 8031 TO PC "R" 475 ; 476 82DB SEIS: 477 82DB 90 1F E0 MOV DPTR,#1FE0H 478 82DE 74 03 MOV A,#3 479 82E0 93 MOVC A,@A+DPTR 480 82E1 51 9A ACALL REC 481 82E3 74 04 MOV A,#4 482 82E5 93 MOVC A,@A+DPTR 483 82E6 51 9A ACALL REC 484 82E8 74 02 MOV A,#2 485 82EA 93 MOVC A,@A+DPTR 486 82EB 51 9A ACALL REC 487 82ED E4 CLR A 488 82EE 93 MOVC A,@A+DPTR 489 82EF 51 9A ACALL REC 490 82F1 74 01 MOV A,#1 491 82F3 93 MOVC A,@A+DPTR 492 82F4 51 9A ACALL REC 493 82F6 74 07 MOV A,#7 494 82F8 93 MOVC A,@A+DPTR 495 82F9 51 9A ACALL REC 235 ;PUNTERO ;DPH ;DPL ;PSW ;ACC ;B ;SP ITF51 496 82FB E5 80 MOV A,P0 497 82FD 51 9A ACALL REC 498 82FF E5 90 MOV A,P1 499 8301 51 9A ACALL REC 500 8303 E5 A0 MOV A,P2 501 8305 51 9A ACALL REC 502 8307 E5 B0 MOV A,P3 503 8309 51 9A ACALL REC 504 830B E5 B8 MOV A,IP 505 830D 51 9A ACALL REC 506 830F E5 A8 MOV A,IE 507 8311 51 9A ACALL REC 508 8313 E5 89 MOV A,TMOD 509 8315 51 9A ACALL REC 510 8317 E5 88 MOV A,TCON 511 8319 51 9A ACALL REC 512 831B E5 8C MOV A,TH0 513 831D 51 9A ACALL REC 514 831F E5 8A MOV A,TL0 515 8321 51 9A ACALL REC 516 8323 E5 8D MOV A,TH1 517 8325 51 9A ACALL REC 518 8327 E5 8B MOV A,TL1 519 8329 51 9A ACALL REC 520 832B E5 98 MOV A,SCON 521 832D 51 9A ACALL REC 522 832F E5 99 MOV A,SBUF 523 8331 51 9A ACALL REC 524 8333 E5 87 MOV A,PCON 525 8335 51 9A ACALL REC 526 8337 74 10 MOV A,#10H 527 8339 93 MOVC A,@A+DPTR 528 833A 51 9A ACALL REC 529 833C 74 11 MOV A,#11H 530 833E 93 MOVC A,@A+DPTR 531 833F 51 9A ACALL REC ;P0 ;P1 ;P2 ;P3 ;IP ;IE ;TMOD ;TCON ;TH0 ;TL0 ;TH1 ;TL1 ;SCON ;SBUF ;PCON ;PCH ;PCL 532 ; 533 ;POSICIONES DE MEMORIA INTERNA 534 ; 535 8341 E5 D0 MOV A,PSW 536 8343 54 18 ANL A,#00011000B 537 8345 B4 00 02 CJNE A,#0,X60 538 8348 80 0A SJMP X64 539 834A B4 08 02 540 834D 80 16 541 834F B4 10 49 X60 CJNE A,#8,X61 X61 CJNE A,#10H,X67 SJMP X65 236 ;MASCARA RS(0-1) ;SI BANCO 0 ;SI BANCO 1 ITF51 542 8352 80 2C SJMP X66 543 ; 544 ;BANCO 0 545 ; 546 8354 547 8354 X64: 78 7F MOV R0,#7FH 548 8356 E6 549 8357 51 9A ACALL REC 550 8359 18 DEC R0 551 835A B8 07 F9 CJNE R0,#7,X6A 835D 71 B6 552 553 ;SI BANCO 2 X6A MOV A,@R0 ;ENVI0 7Fh ; 554 ACALL REGISTER ; 555 835F C3 CLR C ;NO "T" 556 8360 C2 D5 CLR PSW.5 ;NO "G" 557 8362 02 80 F7 LJMP SALIR 558 ; 559 ;BANCO 1 560 ; 561 8365 X65: 562 8365 78 7F 563 8367 E6 564 8368 51 9A ACALL REC 565 836A 18 DEC R0 566 836B B8 0F F9 CJNE R0,#FH,X6B 567 568 MOV R0,#7FH X6B MOV A,@R0 ;7Fh a 10h ; 836E 71 B6 570 8370 78 07 571 8372 E6 572 8373 51 9A ACALL REC 573 8375 D8 FB DJNZ R0,X6BB 574 8377 E6 MOV A,@R0 575 8378 51 9A ACALL REC ;00 569 ACALL REGISTER ; 576 MOV R0,#7 X6BB MOV A,@R0 ;07 a 01 ; 577 837A C3 CLR C ;NO "T" 578 837B C2 D5 CLR PSW.5 ;NO "G" 579 837D 02 80 F7 LJMP SALIR 580 ;BANCO 2 581 ; 582 8380 583 8380 78 7F X66: 584 8382 E6 585 8383 51 9A ACALL REC 586 8385 18 DEC R0 587 8386 B8 17 F9 CJNE R0,#17H,X6C MOV R0,#7FH X6C MOV A,@R0 237 ;7Fh a 18h A 08h ITF51 588 589 ; 8389 71 B6 590 ACALL REGISTER ; 591 838B 78 0F 592 838D E6 593 838E 51 9A ACALL REC 594 8390 D8 FB DJNZ R0,X6CC 595 8392 E6 MOV A,@R0 596 8393 51 9A ACALL REC ;00 597 MOV R0,#FH X6CC MOV A,@R0 ;0Fh a 01h ; 598 8395 C3 CLR C ;NO "T" 599 8396 C2 D5 CLR PSW.5 ;NO "G" 600 8398 02 80 F7 LJMP SALIR 601 ; 602 ;BANCO 3 603 ; 604 839B 605 839B X67: 78 7F MOV R0,#7FH 606 839D E6 607 839E 51 9A ACALL REC 608 83A0 18 DEC R0 609 83A1 B8 1F F9 CJNE R0,#1FH,X6D 610 611 X6D MOV A,@R0 ;7Fh a 20h ; 83A4 71 B6 612 ACALL REGISTER ; 613 83A6 78 18 614 83A8 E6 MOV R0,#18H X6DD MOV A,@R0 615 83A9 51 9A ACALL REC 616 83AB D8 FB DJNZ R0,X6DD 617 83AD E6 MOV A,@R0 618 83AE 51 9A ACALL REC ;00 620 83B0 C3 CLR C ;NO "T" 621 83B1 C2 D5 CLR PSW.5 ;NO "G" 622 83B3 02 80 F7 LJMP SALIR 619 ; 623 624 ;18h a 01h ; 83B6 REGISTER: 625 ; 626 83B6 90 1F E0 MOV DPTR,#1FE0H 627 83B9 74 0F MOV A,#0FH 628 83BB F5 F0 629 83BD 93 MOVC A,@A+DPTR 630 83BE 51 9A ACALL REC 631 83C0 E5 F0 MOV A,B 632 83C2 14 DEC A 633 83C3 B4 07 F5 CJNE A,#7,X6K X6K MOV B,A 238 ;R7 a R0 ITF51 634 83C6 22 RET 635 ; 636 ; 637 ;PARA LA TRANSFERENCIA DE UN BYTE HACIA EL PC 638 ;SE RECIBE DIRECCION. 639 ; 640 83C7 641 83C7 20 B2 FD SIETE: JB P3.2,SIETE 642 83CA 90 C0 00 MOV DPTR,#C000H 643 83CD E0 MOVX A,@DPTR 644 83CE FF 645 83CF 20 B2 FD MOV R7,A 646 83D2 E0 MOVX A,@DPTR 647 83D3 F5 82 MOV DPL,A X70 JB P3.2,X70 648 83D5 EF MOV A,R7 649 83D6 F5 83 MOV DPH,A 650 83D8 E0 MOVX A,@DPTR ;CAPTURAR BYTE SOLICITADO 651 83D9 51 9A ACALL REC ;ENVIO BYTE 653 83DB C3 CLR C ;NO "T" 654 83DC C2 D5 CLR PSW.5 ;NO "G" 655 83DE 02 80 F7 LJMP SALIR 652 ; 656 ; 657 ;RUTINA PARA LA MODIFICACION DE UNA POSICION DE MEMORIA 658 ;SE RECIBE DIRECCION Y DATO; SE ENVIA DATO ESCRITO 659 ; 660 83E1 OCHO: 661 83E1 20 B2 FD JB P3.2,OCHO 662 83E4 90 C0 00 MOV DPTR,#C000H 663 83E7 E0 MOVX A,@DPTR 664 83E8 FF MOV R7,A 665 83E9 20 B2 FD 666 83EC E0 MOVX A,@DPTR 667 83ED FE MOV R6,A 668 83EE 20 B2 FD 669 83F1 E0 X80 X81 JB P3.2,X80 JB P3.2,X81 MOVX A,@DPTR 670 83F2 FD MOV R5,A 671 83F3 EF MOV A,R7 672 83F4 F5 83 MOV DPH,A 673 83F6 EE MOV A,R6 674 83F7 F5 82 MOV DPL,A 675 83F9 ED MOV A,R5 676 83FA F0 MOVX @DPTR,A 677 83FB E0 MOVX A,@DPTR 678 83FC 51 9A 679 ACALL REC ; 239 ITF51 680 83FE C3 CLR C ;NO "T" 681 83FF C2 D5 CLR PSW.5 ;NO "G" 682 8401 02 80 F7 LJMP SALIR 683 ; 684 ;RUTINA PARA LA MODIFICACION DE BYTES INTERNOS 685 ;SE RECIBE POSICION Y BYTE. SE DEVUELVE BYTE 686 ; 687 8404 NUEVE: 688 8404 20 B2 FD JB P3.2,NUEVE 689 8407 90 C0 00 MOV DPTR,#C000H 690 840A E0 MOVX A,@DPTR 691 840B F8 MOV R0,A 692 840C 20 B2 FD 693 840F E0 694 8410 F5 F0 695 X90 JB P3.2,X90 MOVX A,@DPTR MOV B,A ;VER SI LA POSICION ES DEL BANCO DE REGISTROS ACTUAL 696 8412 : 697 8412 E5 D0 MOV A,PSW 698 8414 54 18 ANL A,#00011000B 699 8416 B4 00 09 CJNE A,#0,XA1 700 8419 E8 MOV A,R0 701 841A C3 CLR C 702 841B 94 08 SUBB A,#8 703 841D E8 MOV A,R0 704 841E 40 3E JC SI_REG 705 8420 80 30 SJMP NO_REG 706 8422 B4 08 0E XA1 CJNE A,#8,XA2 707 8425 E8 MOV A,R0 708 8426 C3 CLR C 709 8427 94 10 SUBB A,#16 710 8429 50 27 JNC NO_REG 711 842B C3 CLR C 712 842C E8 MOV A,R0 713 842D 94 08 SUBB A,#8 714 842F 40 21 JC NO_REG 715 8431 80 2B SJMP SI_REG 716 8433 B4 10 0E 717 8436 E8 MOV A,R0 718 8437 C3 CLR C 719 8438 94 18 SUBB A,#24 720 843A 50 16 JNC NO_REG 721 843C C3 CLR C 722 843D E8 MOV A,R0 723 843E 94 10 SUBB A,#16 XA2 ;SALTA SI ES DE ESTE BANCO ;NO ES DEL BANCO_1 ;NO ES DEL BANCO_1 CJNE A,#10H,XA3 724 8440 40 10 JC NO_REG 725 8442 80 1A SJMP SI_REG 240 ;NO ES DEL BANCO_2 ;NO ES DEL BANCO_2 ITF51 726 8444 XA3: 727 8444 E8 MOV A,R0 728 8445 C3 CLR C 729 8446 94 20 SUBB A,#32 730 8448 50 08 JNC NO_REG 731 844A C3 CLR C ;NO ES DEL BANCO_3 732 844B E8 MOV A,R0 733 844C 94 18 SUBB A,#24 734 844E 40 02 JC NO_REG 735 8450 80 0C SJMP SI_REG 736 8452 737 8452 E5 F0 MOV A,B 738 8454 F6 MOV @R0,A 739 8455 E6 MOV A,@R0 740 8456 51 9A ACALL REC 741 8458 C3 CLR C ;NO "T" 742 8459 C2 D5 CLR PSW.5 ;NO "G" 743 845B 02 80 F7 LJMP SALIR 744 845E 745 845E 90 1F E8 MOV DPTR,#1FE8H 746 8461 25 82 ADD A,DPL 747 8463 F5 82 MOV DPL,A 748 8465 E5 F0 MOV A,B 749 8467 F0 MOVX @DPTR,A 750 8468 E0 MOVX A,@DPTR 751 8469 51 9A ACALL REC 752 846B C3 CLR C ;NO "T" 753 846C C2 D5 CLR PSW.5 ;NO "G" 754 846E 02 80 F7 LJMP SALIR ;NO ES DEL BANCO_3 NO_REG: SI_REG: ;APUNTA R0 755 ; 756 ;RUTINA PARA LA TRANSFERENCIA AL PC DE BYTE INTERNO 757 ;SE RECIBE BYTE DE POSICION Y SE ENVIA BYTE DATO. 758 ; 759 8471 DIEZ: 760 8471 20 B2 FD JB P3.2,DIEZ 761 8474 90 C0 00 MOV DPTR,#C000H 762 8477 E0 MOVX A,@DPTR 763 8478 B4 00 06 CJNE A,#0,XB_0 764 847B 90 1F E8 MOV DPTR,#1FE8H 765 847E E0 MOVX A,@DPTR 80 02 766 847F 767 8481 768 8481 F8 MOV R0,A 769 8482 E6 MOV A,@R0 770 8483 771 8483 SJMP XB_1 XB_0: XB_1: 51 9A ACALL REC 241 ;POR SI LA POSICION ES R0 ITF51 772 8485 C3 CLR C ;NO "T" 773 8486 C2 D5 CLR PSW.5 ;NO "G" 774 8488 02 80 F7 LJMP SALIR 775 ; 776 ; 777 ;RUTINA PARA LA MODIFICACION DE REGISTROS ESPECIALES 778 ;SE RECIBE DPH Y DL, SE DEVUELVE DL 779 ; 780 848B ONCE: 781 848B 20 B2 FD JB P3.2,ONCE 782 848E C2 D5 CLR PSW.5 783 8490 90 C0 00 MOV DPTR,#C000H 784 8493 E0 MOVX A,@DPTR 785 8494 FF MOV R7,A 786 8495 787 8495 20 B2 FD JB P3.2,X110 788 8498 E0 MOVX A,@DPTR 789 8499 FE MOV R6,A EF X110: 790 849A 791 849B MOV A,R7 792 849B B4 E0 05 CJNE A,#E0H,R0a 793 849E E4 CLR A 794 849F D1 05 ACALL SFREG 795 84A1 A1 FD 796 84A3 B4 F0 06 797 84A6 74 01 MOV A,#1H 798 84A8 D1 05 ACALL SFREG 799 84AA A1 FD 800 84AC B4 D0 06 801 84AF 74 02 MOV A,#2 802 84B1 D1 05 ACALL SFREG 803 84B3 A1 FD 804 84B5 B4 81 06 805 84B8 74 07 MOV A,#7 806 84BA D1 05 ACALL SFREG 807 84BC A1 FD AJMP ESP_R 808 84BE B4 83 06 809 84C1 74 03 MOV A,#3 810 84C3 D1 05 ACALL SFREG 811 84C5 A1 FD AJMP ESP_R 812 84C7 B4 82 06 813 84CA 74 04 MOV A,#4 814 84CC D1 05 ACALL SFREG 815 84CE A1 FD AJMP ESP_R 816 84D0 B4 80 09 817 84D3 20 D5 02 VER: ;ACC AJMP ESP_R R0a CJNE A,#F0H,R1a ;B AJMP ESP_R R1a CJNE A,#D0H,R2a ;PSW AJMP ESP_R R2a R3a R4a R5a CJNE A,#81H,R3a ;SP CJNE A,#83H,R4a ;DPH CJNE A,#82H,R5a CJNE A,#80H,R6a JB PSW.5,R6X 242 ;DPL ITF51 818 84D6 8E 80 MOV 80H,R6 819 84D8 E5 80 820 84DA A1 FD R6X MOV A,80H 821 84DC B4 90 09 822 84DF 20 D5 02 JB PSW.5,R7X 823 84E2 8E 90 MOV 90H,R6 AJMP ESP_R R6a R7X CJNE A,#90H,R7a 824 84E4 E5 90 825 84E6 A1 FD MOV A,90H 826 84E8 B4 A0 09 827 84EB 20 D5 02 828 84EE 8E A0 829 84F0 E5 A0 830 84F2 A1 FD 831 84F4 B4 B0 09 832 84F7 20 D5 02 JB PSW.5,R9X 833 84FA 8E B0 MOV B0H,R6 834 84FC E5 B0 835 84FE A1 FD 836 8500 B4 B8 09 837 8503 20 D5 02 JB PSW.5,R10X 838 8506 8E B8 MOV B8H,R6 839 8508 E5 B8 840 850A A1 FD 841 850C B4 A8 09 842 850F 20 D5 02 JB PSW.5,R11X 843 8512 8E A8 MOV A8H,R6 844 8514 E5 A8 AJMP ESP_R R7a CJNE A,#A0H,R8 JB PSW.5,R8X MOV A0H,R6 R8X MOV A,A0H AJMP ESP_R R8 R9X CJNE A,#B0H,R9 MOV A,B0H AJMP ESP_R R9 R10X CJNE A,#B8H,R10 MOV A,B8H AJMP ESP_R R10 R11X CJNE A,#A8H,R11 MOV A,A8H 845 8516 A1 FD 846 8518 B4 89 09 AJMP ESP_R 847 851B 20 D5 02 JB PSW.5,R12X 848 851E 8E 89 MOV 89H,R6 R11 849 8520 E5 89 850 8522 A1 FD 851 8524 B4 88 09 852 8527 20 D5 02 JB PSW.5,R13X 853 852A 8E 88 MOV 88H,R6 854 852C E5 88 855 852E A1 FD 856 8530 B4 8C 09 857 8533 20 D5 02 858 8536 8E 8C 859 8538 E5 8C 860 853A A1 FD 861 853C B4 8A 09 R12X CJNE A,#89H,R12 MOV A,89H AJMP ESP_R R12 R13X CJNE A,#88H,R13 MOV A,88H AJMP ESP_R R13 CJNE A,#8CH,R14 JB PSW.5,R14X MOV 8CH,R6 R14X MOV A,8CH AJMP ESP_R R14 CJNE A,#8AH,R15 862 853F 20 D5 02 JB PSW.5,R15X 863 8542 8E 8A MOV 8AH,R6 243 ITF51 864 8544 E5 8A R15X MOV A,8AH 865 8546 A1 FD 866 8548 B4 8D 09 AJMP ESP_R 867 854B 20 D5 02 JB PSW.5,R16X 868 854E 8E 8D MOV 8DH,R6 869 8550 E5 8D R15 R16X CJNE A,#8DH,R16 MOV A,8DH 870 8552 A1 FD 871 8554 B4 8B 09 872 8557 20 D5 02 JB PSW.5,R17X 873 855A 8E 8B MOV 8BH,R6 874 855C E5 8B 875 855E A1 FD 876 8560 B4 98 09 877 8563 20 D5 02 878 8566 8E 98 879 8568 E5 98 880 856A A1 FD 881 856C B4 99 09 AJMP ESP_R R16 R17X CJNE A,#8BH,R17 MOV A,8BH AJMP ESP_R R17 CJNE A,#98H,R18 JB PSW.5,R18X MOV 98H,R6 R18X MOV A,98H AJMP ESP_R R18 CJNE A,#99H,R19 882 856F 20 D5 02 JB PSW.5,R19X 883 8572 8E 99 MOV 99H,R6 884 8574 E5 99 885 8576 A1 FD 886 8578 B4 87 09 R19X MOV A,99H AJMP ESP_R R19 CJNE A,#87H,R20 887 857B 20 D5 02 JB PSW.5,R20X 888 857E 8E 87 MOV 87H,R6 889 8580 E5 87 890 8582 A1 FD R20X MOV A,87H AJMP ESP_R 891 ; 892 R20: 893 ; ;REGISTROS R0 a R7 894 8584 75 83 1F MOV DPH,#1FH 895 8587 B4 00 0B CJNE A,#0,R21 896 858A 75 82 E8 MOV DPL,#E8H 897 858D 20 D5 02 JB PSW.5,R21X 898 8590 EE MOV A,R6 899 8591 F0 MOVX @DPTR,A 900 8592 E0 901 8593 A1 FD 902 903 R21X MOVX A,@DPTR AJMP ESP_R ; 8595 R21: 904 8595 B4 01 0B CJNE A,#1,R22 905 8598 75 82 E9 MOV DPL,#E9H 906 859B 20 D5 02 JB PSW.5,R22X 907 859E EE MOV A,R6 908 859F F0 909 85A0 E0 MOVX @DPTR,A R22X MOVX A,@DPTR 244 ITF51 910 85A1 A1 FD 912 85A3 B4 02 0B 913 85A6 75 82 EA MOV DPL,#EAH 914 85A9 20 D5 02 JB PSW.5,R23X 915 85AC EE MOV A,R6 916 85AD F0 917 85AE E0 918 85AF A1 FD 911 AJMP ESP_R ; 919 R22 CJNE A,#2,R23 MOVX @DPTR,A R23X MOVX A,@DPTR AJMP ESP_R ; 920 85B1 B4 03 0B 921 85B4 75 82 EB R23 MOV DPL,#EBH CJNE A,#3,RE1 922 85B7 20 D5 02 JB PSW.5,R24X 923 85BA EE MOV A,R6 924 85BB F0 925 85BC E0 926 85BD A1 FD 927 85BF MOVX @DPTR,A R24X MOVX A,@DPTR AJMP ESP_R RE1: 928 85BF B4 04 0B CJNE A,#4,RE2 929 85C2 75 82 EC MOV DPL,#ECH 930 85C5 20 D5 02 JB PSW.5,R25X 931 85C8 EE MOV A,R6 932 85C9 F0 MOVX @DPTR,A 933 85CA E0 934 85CB A1 FD 935 R25X MOVX A,@DPTR AJMP ESP_R ; 936 85CD B4 05 0B 937 85D0 75 82 ED MOV DPL,#EDH 938 85D3 20 D5 02 JB PSW.5,R26X 939 85D6 EE MOV A,R6 940 85D7 F0 MOVX @DPTR,A 941 85D8 E0 942 85D9 A1 FD 943 RE2 R26X CJNE A,#5,RE3 MOVX A,@DPTR AJMP ESP_R ; 944 85DB B4 06 0B 945 85DE 75 82 EE RE3 CJNE A,#6,RE4 MOV DPL,#EEH 946 85E1 20 D5 02 JB PSW.5,R27X 947 85E4 EE MOV A,R6 948 85E5 F0 MOVX @DPTR,A 949 85E6 E0 950 85E7 A1 FD 951 R27X MOVX A,@DPTR AJMP ESP_R ; 952 85E9 B4 07 0B 953 85EC 75 82 EF RE4 CJNE A,#7,RE5 MOV DPL,#EFH 954 85EF 20 D5 02 JB PSW.5,R28X 955 85F2 EE MOV A,R6 245 ITF51 956 85F3 F0 957 85F4 E0 958 85F5 A1 FD 959 MOVX @DPTR,A R28X MOVX A,@DPTR AJMP ESP_R ; 960 85F7 RE5 961 85F7 C3 CLR C ;NO "T" 962 85F8 C2 D5 CLR PSW.5 ;NO "G" 963 85FA 02 80 F7 LJMP SALIR 964 85FD 965 85FD ESP_R: 51 9A ACALL REC 966 85FF C3 CLR C ;NO "T" 967 8600 C2 D5 CLR PSW.5 ;NO "G" 968 8602 02 80 F7 LJMP SALIR 969 970 ; 8605 SFREG: 971 ; 972 8605 90 1F E0 MOV DPTR,#1FE0H 973 8608 FF MOV R7,A 974 8609 E5 82 MOV A,DPL 975 860B 2F ADD A,R7 976 860C F5 82 MOV DPL,A 977 860E 20 D5 02 JB PSW.5,SFREG1 978 8611 EE MOV A,R6 979 8612 F0 980 8613 981 8613 E0 MOVX A,@DPTR 982 8614 22 RET MOVX @DPTR,A SFREG1: 983 ;RUTINA PARA VISUALIZAR REGISTROS ESPECIALES 984 ;SE RECIBE DPH Y SE ENVIA DL 985 ; 986 8615 DOCE: 987 8615 20 B2 FD JB P3.2,DOCE 988 8618 90 C0 00 MOV DPTR,#C000H 989 861B E0 MOVX A,@DPTR 990 861C D2 D5 SETB PSW.5 991 861E 02 84 9B LJMP VER 992 ; 993 ;RUTINA GO CON RUPTURA 994 ; 995 8621 CATORCE: 996 8621 20 B2 FD 997 8624 90 C0 00 MOV DPTR,#C000H 998 8627 E0 MOVX A,@DPTR 999 8628 FF MOV R7,A 1000 8629 20 B2 FD 1001 862C E0 PP_1 PP_2 JB P3.2,PP_1 JB P3.2,PP_2 MOVX A,@DPTR 246 ;CAPTURAR PCH(ini) ITF51 1002 862D FE MOV R6,A 1003 862E 20 B2 FD 1004 8631 E0 MOVX A,@DPTR 1005 8632 FD MOV R5,A 1006 8633 20 B2 FD 1007 8636 E0 PP_3 PP_4 ;CAPTURAR PCL(ini) JB P3.2,PP_3 ;CAPTURAR PCH(fin) JB P3.2,PP_4 MOVX A,@DPTR 1008 8637 FC MOV R4,A 1009 8638 90 1F E5 MOV DPTR,#1FE5H 1010 863B EF MOV A,R7 1011 863C F0 MOVX @DPTR,A 1012 863D 05 82 INC DPL 1013 863F EE MOV A,R6 1014 8640 F0 MOVX @DPTR,A ;PUSH PCL(ini) 1015 8641 90 1F F5 MOV DPTR,#1FF5H ;SE GUARDA PC 1016 8644 ED MOV A,R5 1017 8645 F0 MOVX @DPTR,A 1018 8646 05 82 INC DPL 1019 8648 EC MOV A,R4 1020 8649 F0 MOVX @DPTR,A 1021 864A 8D 83 MOV 83H,R5 1022 864C 8C 82 MOV 82H,R4 1023 864E C0 83 PUSH DPH 1024 8650 C0 82 PUSH DPL ;CAPTURAR PCL(fin) ;PUSH PCH(ini) ;PUSH PCH(fin) ;PUSH PCL(fin) 1025 8652 D1 69 ACALL SALVAR 1026 8654 D0 82 POP DPL 1027 8656 D0 83 POP DPH 1028 8658 74 02 MOV A,#02H ;INSTRUCCION DE LJMP ;CODIGO LCALL 1029 865A F0 MOVX @DPTR,A 1030 865B A3 INC DPTR 1031 865C 74 86 MOV A,#86H 1032 865E F0 MOVX @DPTR,A 1033 865F A3 INC DPTR 1034 8660 74 9D MOV A,#9DH 1035 8662 F0 MOVX @DPTR,A 1036 ;SE SALVAN 3 BYTES ;BYTE ALTO DIREC ;BYTE BAJO DIREC ; 1037 8663 C3 CLR C ;NO "T" 1038 8664 D2 D5 SETB PSW.5 ;SI "G" 1039 8666 02 80 F7 LJMP SALIR ;COMIENZO EJECUCION 1040 ; 1041 ;RUTINA PARA SALVAR 3 BYTES A PARTIR DE DPTR 1042 ;DESTINO A PARTIR DE 7F2h 1043 ; 1044 8669 1045 8669 SALVAR: E0 MOVX A,@DPTR 1046 866A FD MOV R5,A 1047 866B A3 INC DPTR 247 ;LEER BYTE n' 1 ITF51 1048 866C E0 MOVX A,@DPTR 1049 866D FC MOV R4,A 1050 866E A3 INC DPTR 1051 866F E0 MOVX A,@DPTR 1052 8670 FB MOV R3,A 1053 8671 90 1F F2 MOV DPTR,#1FF2H 1054 8674 ED MOV A,R5 1055 8675 F0 MOVX @DPTR,A 1056 8676 05 82 INC DPL 1057 8678 EC MOV A,R4 1058 8679 F0 MOVX @DPTR,A 1059 867A 05 82 INC DPL 1060 867C EB MOV A,R3 1061 867D F0 MOVX @DPTR,A 1062 867E 22 ;LEER BYTE n' 2 ;LEER BYTE n' 3 ;GUARDAR BYTE n' 1 ;GUARDAR BYTE n' 2 ;GUARDAR BYTE n' 3 RET 1063 ; 1064 ;RUTINA PARA RESTAURAR 3 BYTES DESDE 07F2h HASTA DPTR 1065 ; 1066 867F 1067 867F AF 83 RESTAURAR: MOV R7,83H 1068 8681 AE 82 MOV R6,82H 1069 8683 90 1F F2 MOV DPTR,#1FF2H 1070 8686 E0 MOVX A,@DPTR 1071 8687 FD MOV R5,A 1072 8688 05 82 INC DPL 1073 868A E0 MOVX A,@DPTR 1074 868B FC MOV R4,A 1075 868C 05 82 INC DPL 1076 868E E0 MOVX A,@DPTR 1077 868F FB MOV R3,A 1078 8690 8F 83 MOV 83H,R7 1079 8692 8E 82 MOV 82H,R6 1080 8694 ED MOV A,R5 1081 8695 F0 MOVX @DPTR,A 1082 8696 A3 INC DPTR 1083 8697 EC MOV A,R4 1084 8698 F0 MOVX @DPTR,A 1085 8699 A3 INC DPTR 1086 869A EB MOV A,R3 1087 869B F0 MOVX @DPTR,A 1088 869C 22 ; 1090 ; 1091 ; 1093 ;LEER BYTE n' 3 DE STACK ;RESTAURAR BYTE n' 1 ;RESTAURAR BYTE n' 2 ;RESTAURAR BYTE n' 3 RUTINA DE ATENCION A PUNTO DE RUPTURA ; 869D ;LEER BYTE n' 2 DE STACK RET 1089 1092 ;LEER BYTE n' 1 DE STACK RUPTURA: 248 ITF51 1094 869D C2 AF CLR IE.7 1095 869F C0 E0 PUSH A 1096 86A1 51 AE ACALL AVISO 1097 86A3 D0 E0 POP A 1098 86A5 C0 82 PUSH DPL 1099 86A7 C0 83 PUSH DPH 1100 86A9 90 1F E0 MOV DPTR,#1FE0H 1101 86AC F0 MOVX @DPTR,A 1102 86AD 75 82 0B MOV DPL,#0BH 1103 86B0 EB MOV A,R3 1104 86B1 F0 MOVX @DPTR,A 1105 86B2 EC MOV A,R4 1106 86B3 05 82 INC DPL 1107 86B5 F0 MOVX @DPTR,A 1108 86B6 05 82 INC DPL 1109 86B8 ED MOV A,R5 1110 86B9 F0 MOVX @DPTR,A 1111 86BA 05 82 INC DPL 1112 86BC EE MOV A,R6 1113 86BD F0 MOVX @DPTR,A 1114 86BE 05 82 INC DPL 1115 86C0 EF MOV A,R7 1116 86C1 F0 MOVX @DPTR,A 1117 86C2 75 82 03 MOV DPL,#3 1118 86C5 D0 E0 POP A 1119 86C7 F0 MOVX @DPTR,A 1120 86C8 05 82 INC DPL 1121 86CA D0 E0 POP A 1122 86CC F0 MOVX @DPTR,A 1123 1124 ;DESACTIVAR INTERRUP ;DATA/CODE ;PUSH ACC ;PUSH R3 ;PUSH R4 ;PUSH R5 ;PUSH R6 ;PUSH R7 ;PUSH DPH ;PUSH DPH ; 86CD 90 1F F5 MOV DPTR,#1FF5H 1125 86D0 E0 MOVX A,@DPTR 1126 86D1 FD MOV R5,A 1127 86D2 05 82 INC DPL 1128 86D4 E0 MOVX A,@DPTR 1129 86D5 FC MOV R4,A 1130 86D6 90 1F F0 MOV DPTR,#1FF0H 1131 86D9 ED MOV A,R5 1132 86DA F0 MOVX @DPTR,A 1133 86DB 05 82 INC DPL 1134 86DD EC MOV A,R4 1135 86DE F0 MOVX @DPTR,A 1136 86DF 8D 83 MOV 83H,R5 1137 86E1 8C 82 MOV 82H,R4 1138 86E3 D1 7F ACALL RESTAURAR 1139 86E5 74 69 MOV A,#69H 249 ;POP PCH(fin) ;POP PCL(fin) ;PUSH PCH(fin) ;PUSH PCL(fin) ;SE RECUPERAN 3 BYTES ITF51 1140 86E7 90 1F E0 MOV DPTR,#1FE0H 1141 86EA 74 0F MOV A,#FH 1142 86EC 93 MOVC A,@A+DPTR 1143 86ED FF MOV R7,A 1144 86EE 74 0E MOV A,#EH 1145 86F0 93 MOVC A,@A+DPTR 1146 86F1 FE MOV R6,A 1147 86F2 74 0D MOV A,#DH 1148 86F4 93 MOVC A,@A+DPTR 1149 86F5 FD MOV R5,A 1150 86F6 74 0C MOV A,#CH 1151 86F8 93 MOVC A,@A+DPTR 1152 86F9 FC MOV R4,A 1153 86FA 74 0B MOV A,#BH 1154 86FC 93 MOVC A,@A+DPTR 1155 86FD FB MOV R3,A 1156 86FE 74 04 MOV A,#4 1157 8700 93 MOVC A,@A+DPTR 1158 8701 C0 E0 PUSH A 1159 8703 74 03 MOV A,#3 1160 8705 93 MOVC A,@A+DPTR 1161 8706 C0 E0 PUSH A 1162 8708 E4 CLR A 1163 8709 93 MOVC A,@A+DPTR 1164 870A D0 83 POP DPH 1165 870C D0 82 POP DPL 1166 870E D2 AF SETB IE.7 1167 8710 02 DB 02 1168 8711 80 DB 80H 1169 8712 22 DB 22H 1170 ; 1171 9FFE 1172 9FFE 1173 9FFE 1174 A000 ORG 9FFEH ULTIMA: 80 FE SJMP ULTIMA END 250 ;ACTIVACION INTERRUP ITF51 ************* S Y M B O L I C R E F E R E N C E T A B L E ************* : 8412 AVISO 82AE CATORCE 8621 CERO 8176 CINC 82C2 CUAT 8234 D0 80A3 D1 80A9 D10 80DF D11 80E5 D12 80EB D13 80F1 D2 80AF D3 80B5 D4 80BB D5 80C1 D6 80C7 D7 80CD D8 80D3 D9 80D9 DFF 8096 DIEZ 8471 DOCE 8615 DOS 8192 ESP_R 85FD NO_REG 8452 NUEVE 8404 OCHO 83E1 ONCE 848B PP_1 8621 PP_2 8629 PP_3 862E PP_4 8633 R0a 84A3 R10 850C R10X 8508 R11 8518 R11X 8514 R12 8524 R12X 8520 R13 8530 R13X 852C R14 853C R14X 8538 R15 8548 R15X 8544 R16 8554 R16X 8550 R17 8560 R17X 855C R18 856C R18X 8568 R19 8578 R19X 8574 R1a 84AC R20 8584 R20X 8580 R21 8595 R21X 8592 R22 85A3 R22X 85A0 R23 85B1 R23X 85AE R24X 85BC R25X 85CA R26X 85D8 R27X 85E6 R28X 85F4 R2a 84B5 R3a 84BE R4a 84C7 R5a 84D0 R6X 84D8 R6a 84DC R7X 84E4 R7a 84E8 R8 84F4 R8X 84F0 R9 8500 R9X 84FC RE1 85BF RE2 85CD RE3 85DB RE4 85E9 RE5 85F7 REC 829A REG3 8243 REGISTER 83B6 RESTAURAR 867F RUPTURA 869D SAL 8147 SAL1 8153 SALIR 80F7 SALIR_1 814C SALIR_2 815E SALVAR 8669 SEIS 82DB SFREG 8605 SFREG1 8613 SIETE 83C7 SI_REG 845E TRECE 8165 TRES 81DE ULTIMA 9FFE UNO 8211 VER 849B X1 819B X10 8219 X110 8495 X2 81A1 X20 81AB X21 81D7 X3 81A6 X32 81FB X33 820E X42 82A2 X43 82B6 X50 82CA X60 834A X61 834F X64 8354 X65 8365 X66 8380 X67 839B X6A 8356 X6B 8367 X6BB 8372 X6C 8382 X6CC 838D X6D 839D X6DD 83A8 X6K 83BB X70 83CF X80 83E9 X81 83EE X90 840C XA1 8422 XA2 8433 XA3 8444 XB_0 8481 XB_1 8483 Y30 81E7 Y31 81ED Y32 81F2 LINES ASSEMBLED : 1174 ASSEMBLY ERRORS : Código 5. Programa Monitor-Modifi.ASM 251 0 ITF51 5.4 Protocolo del bus de comunicaciones Figura41. Diagrama temporal de los señales de control en MODO 2 (bidireccional) Tabla 3. Capacitancias 252 ITF51 Tabla 4. Parámetros del bus en el ciclo de lectura Tabla5 . Parámetros del bus en el ciclo de escritura 253 ITF51 Tabla6 . Otros parámetros de tiempo 254 ITF51 6 [1] Bibliografía Kit de Desarrollo para la Familia de Microcontroladores MCS-51 – EMU51 Esteban del Castillo Pérez Dto. de Ingeniería Electrónica, 1989 [2] C and the 8051 – Hardware, Modular Programming, and Multitasking. Thomas W.Schultz Prentice Hall , Inc. 1998 [3] Programación en C – Metodología, estructura de datos y objetos. Luis Joyanes Aguilar – Ignacio Zahonero Martínez McGraw-Hill 2001 [4] 80C51-based 8-bit Microcontrollers data handbook Eindhoven Philips Semiconductors cop. 1996 [5] The 8051 microcontroller and embedded systems Muhammad Ali Mazidi, Janice Gillispie Mazidi Mazidi, Muhammad Ali Upper Saddle River Prentice Hall cop. 2000 [6] http://www.8052.com/ [7] http://dsplabs.utt.ro/aces/ms/docs/80C51_FAM_PROG_GUIDE_1.pdf [8] http://dsplabs.utt.ro/aces/ms/docs/80C51_FAM_HARDWARE_1.pdf 255