DCSLLL

306
Simulador de programas de un sistema de control distribuido TITULACIÓN: EAEI - Ingeniería en Automática y Electrónica Industrial AUTOR: David Capa Benítez. DIRECTOR: Alfonso José Romero Nevado. FECHA: Septiembre / 2006.

description

SISTEMA DE CONTRO DIGITAL

Transcript of DCSLLL

Page 1: DCSLLL

Simulador de programas de un sistema de control distribuido

TITULACIÓN: EAEI - Ingeniería en Automática y Electrónica Industrial

AUTOR: David Capa Benítez.

DIRECTOR: Alfonso José Romero Nevado.

FECHA: Septiembre / 2006.

Page 2: DCSLLL

1 Índice

1

1. Índice 1. Índice ......................................................................................................................... 1

2. Introducción............................................................................................................... 4 2.1. Definiciones............................................................................................................................... 4

2.1.1. Instrumentación y Control .................................................................................................... 4 2.1.2. Sistemas de control distribuido............................................................................................. 4 2.1.3. TPS – La solución de Honeywell.......................................................................................... 4

2.2. Logic Manager (LM) ................................................................................................................. 6 2.2.1. Descripción general .............................................................................................................. 6 2.2.2. Descripción funcional ........................................................................................................... 8 2.2.3. Características....................................................................................................................... 9

2.3. 623-60 MS-DOS Loader ......................................................................................................... 10 2.3.1. Descripción general ............................................................................................................ 10 2.3.2. Características..................................................................................................................... 11 2.3.3. Programa lógico – Código en escalera................................................................................ 12

2.4. Objetivos.................................................................................................................................. 13 2.4.1. Características..................................................................................................................... 13 2.4.2. Exclusiones ......................................................................................................................... 13

3. Funcionamiento del Logic Manager........................................................................ 15 3.1. Mapeado de memoria .............................................................................................................. 15

3.1.1. Módulo de memoria de programa....................................................................................... 15 3.1.2. Módulo de memoria de registros ........................................................................................ 15

3.2. Modos de funcionamiento ....................................................................................................... 17 3.3. Ciclo de ejecución de programa lógico (Ciclo de scan)........................................................... 17

4. Interpretación MS-DOS Loader .............................................................................. 21 4.1. F1 – 620 Loader / Monitor....................................................................................................... 23 4.2. F2 – 620 Stand alone loader (*.ldr) ......................................................................................... 23

4.2.1. Estructura básica del fichero *.ldr....................................................................................... 24 4.2.2. Cabecera ............................................................................................................................. 25 4.2.3. Cuerpo ................................................................................................................................ 38 4.2.4. Cola................................................................................................................................... 106

4.3. F3 – Documentation functions............................................................................................... 107 4.3.1. Nombre de parámetros...................................................................................................... 108 4.3.2. Etiquetas ........................................................................................................................... 108 4.3.3. Comentarios...................................................................................................................... 110

4.4. F4 - Password and security functions .................................................................................... 111 4.5. F5 - I/O configuration utilities ............................................................................................... 112 4.6. F6 - 623 Software configuration *.cfg................................................................................... 112

4.6.1. Codificación y estructura del fichero *.cfg ....................................................................... 115 4.6.2. Mapeado de memoria........................................................................................................ 118

5. Programación......................................................................................................... 122 5.1. Lenguaje de programación .................................................................................................... 122 5.2. Filosofía de programación ..................................................................................................... 123

5.2.1. Descripción básica ............................................................................................................ 123 5.2.2. Interacción de elementos................................................................................................... 126

5.3. ¿Bases de datos o tablas en memoria interna? ....................................................................... 127 5.3.1. Trabajar con bases de datos .............................................................................................. 127 5.3.2. Trabajar con tablas en memoria interna............................................................................ 132 5.3.3. Toma de decisiones........................................................................................................... 133

5.4. Ventana de presentación (Frm_Splash) ................................................................................. 135 5.4.1. Procedimientos y funciones .............................................................................................. 135

Page 3: DCSLLL

1 Índice

2

5.5. Ventana principal (Frm_MDI)............................................................................................... 136 5.5.1. Documentación y decisiones............................................................................................. 136 5.5.2. Variables globales............................................................................................................. 138 5.5.3. Procedimientos y funciones .............................................................................................. 139

5.6. Ventana de configuración (Frm_MDIChildConfiguracion) .................................................. 145 5.6.1. Documentación y decisiones............................................................................................. 145 5.6.2. Procedimientos y funciones .............................................................................................. 146

5.7. Ventana de documentación (Frm_MDIChildDocumentacion).............................................. 150 5.7.1. Documentación y decisiones............................................................................................. 151 5.7.2. Procedimientos y funciones .............................................................................................. 151

5.8. Ventana de memoria interna (Frm_MDIChildMemoria)....................................................... 157 5.8.1. Documentación y decisiones............................................................................................. 157 5.8.2. Variables globales............................................................................................................. 158 5.8.3. Procedimientos y funciones .............................................................................................. 158

5.9. Ventana de programa (Frm_MDIChildPrograma)................................................................. 164 5.9.1. Documentación y decisiones............................................................................................. 165 5.9.2. Variables globales............................................................................................................. 167 5.9.3. Procedimientos y funciones .............................................................................................. 167

5.10. Ventana de simulación (Frm_MDIChildSimulacion)............................................................ 172 5.10.1. Documentación y decisiones............................................................................................. 173 5.10.2. Procedimientos y funciones comunes al formulario ......................................................... 177 5.10.3. Procedimientos y funciones de la sección “Parámetros de simulación” ........................... 178 5.10.4. Procedimientos y funciones de la sección “Evolución de las direcciones”....................... 180 5.10.5. Procedimientos y funciones de la sección “Cronograma” ................................................ 182

5.11. Ventana de selección de ficheros (Frm_ModalSeleccionFicheros) ....................................... 185 5.11.1. Características................................................................................................................... 185 5.11.2. Documentación y decisiones............................................................................................. 185 5.11.3. Procedimientos y funciones .............................................................................................. 186

5.12. Módulo de soporte general (Mdl_General)............................................................................ 187 5.12.1. Documentación y decisiones............................................................................................. 187 5.12.2. Variables globales............................................................................................................. 187 5.12.3. Procedimientos y funciones .............................................................................................. 187 5.12.4. Procedimientos y funciones de codificación y decodificación de números ...................... 188 5.12.5. Procedimientos y funciones de comprobación de valores válidos .................................... 189 5.12.6. Procedimientos y funciones de mapeado de memoria ...................................................... 189

5.13. Módulo de soporte proyecto (Mdl_Proyecto)........................................................................ 191 5.13.1. Documentación y decisiones............................................................................................. 191 5.13.2. Procedimientos y funciones .............................................................................................. 192

5.14. Módulo de soporte para separar líneas de *.ldr (Mdl_SepararLineas) .................................. 201 5.14.1. Documentación y decisiones............................................................................................. 201 5.14.2. Procedimientos y funciones .............................................................................................. 203

5.15. Módulo de soporte interpretar líneas (Mdl_InterpretarLineas).............................................. 208 5.15.1. Documentación y decisiones............................................................................................. 208 5.15.2. Procedimientos y funciones públicas................................................................................ 216 5.15.3. Procedimientos y funciones de acciones de progreso ....................................................... 218 5.15.4. Procedimientos y funciones de acciones de datos............................................................. 221 5.15.5. Procedimientos y funciones auxiliares.............................................................................. 230

5.16. Módulo de soporte tablas internas (Mdl_TablasInternas)...................................................... 234 5.16.1. Documentación y decisiones............................................................................................. 234 5.16.2. Variables globales............................................................................................................. 238 5.16.3. Procedimientos y funciones .............................................................................................. 238 5.16.4. Procedimientos y funciones de ejecución rápida .............................................................. 241 5.16.5. Procedimientos y funciones representación gráfica .......................................................... 244

5.17. Módulo de soporte para bases de datos (Mdl_BasesdeDatos) ............................................... 245 5.17.1. Documentación y decisiones............................................................................................. 245 5.17.2. Procedimientos y funciones .............................................................................................. 246

5.18. Módulo de soporte para simular programas (Mdl_Simular).................................................. 253

Page 4: DCSLLL

1 Índice

3

5.18.1. Documentación y decisiones............................................................................................. 253 5.18.2. Procedimientos y funciones públicas................................................................................ 256 5.18.3. Procedimientos y funciones de acciones de progreso ....................................................... 261 5.18.4. Procedimientos y funciones de acciones de datos............................................................. 262 5.18.5. Procedimientos y funciones auxiliares.............................................................................. 280 5.18.6. Procedimientos y funciones de timers .............................................................................. 282 5.18.7. Procedimientos y funciones saltos NSKR 8192-8447 ...................................................... 283 5.18.8. Procedimientos y funciones de acceso a datos.................................................................. 285 5.18.9. Procedimientos y funciones de evolución de direcciones ................................................. 286

6. Manual de usuario ................................................................................................. 289 6.1. Descripción............................................................................................................................ 289 6.2. Instalación.............................................................................................................................. 289 6.3. Comienzo del programa......................................................................................................... 289 6.4. Apertura de un proyecto ........................................................................................................ 290

6.4.1. Menú Proyecto.................................................................................................................. 291 6.5. Trabajando con un proyecto .................................................................................................. 291

6.5.1. Menú Proyecto.................................................................................................................. 291 6.5.2. Menú Ver .......................................................................................................................... 293 6.5.3. Menú Ventana................................................................................................................... 303 6.5.4. Barra de herramientas ....................................................................................................... 303

7. Conclusiones.......................................................................................................... 305

Page 5: DCSLLL

2 Introducción

4

2. Introducción Antes de explicar el tema del proyecto y los objetivos que se pretenden conseguir, se

considera necesario tener una ligera noción sobre ciertos aspectos relacionados.

2.1. Definiciones De una forma muy simple podemos definir:

2.1.1. Instrumentación y Control Los procesos industriales, cada vez más complejos y exigentes en cuestiones de control

y seguridad, requieren la utilización de sistemas de instrumentación y control.

La instrumentación realiza las medidas sobre ciertas variables de proceso tales como presión, caudal o temperatura…

El control realiza las actuaciones necesarias para mantener dichas variables en los niveles deseados de seguridad y economía, así como otros aspectos que se consideren importantes.

2.1.2. Sistemas de control distribuido Actualmente un gran número de elementos electrónicos e informáticos son utilizados

industrialmente para conseguir dichos objetivos de instrumentación y control.

Así, aparecieron los denominados sistemas de control distribuido, también denominados SCD o DCS (Distributed Control System).

Un sistema de control distribuido integra los diferentes sistemas de control y de información del proceso en un entorno interactivo y coordinado, que permite manipular el proceso de una forma total y remota.

Es decir, un SCD permite visualizar, documentar y sobre todo controlar el funcionamiento global de la planta de producción.

A grandes rasgos está compuesto por los instrumentos de campo, elementos de control locales, los medios de comunicación con los medios principales de control, y finalmente la interfaz humana, también llamada consola de control.

2.1.3. TPS – La solución de Honeywell La empresa Honeywell, dispone del sistema de control distribuido TPS (Total Plant

Solution).

El sistema TPS ha sido diseñado para satisfacer las necesidades de grandes procesos, pero pudiendo adaptarse a procesos pequeños. Sus características principales son:

• Sistema abierto

• Dispositivos de campo inteligentes.

• Interfaz humana con los últimos avances tecnológicos.

• Herramientas avanzadas de ingeniería.

• Completa base de datos histórica en tiempo real.

• Entorno abierto de aplicaciones.

• Probado entorno de control, seguro y robusto.

• Sistema abierto para aplicaciones de gestión de empresas.

Page 6: DCSLLL

2 Introducción

5

Figura 1. Arquitectura del sistema TPS

El sistema TPS, como se puede observar en la figura, se divide en 4 zonas compuestas por diferentes elementos:

• Dispositivos de campo (Field devices)

Dos tipos de elementos:

- Transmisores: Realizan la medida de las variables deseadas y la comunican por distintos medios a la zona de control de proceso.

- Actuadores: Modifican las variables deseadas al valor indicado por la zona de control de proceso.

Fieldbus: Camino que utilizan los dipositivos de campo para comunicarse con los elementos de la zona de control de proceso.

• Control de proceso (Process control)

A partir de la información recibida por los dispositivos de campo (transmisores), y de las órdenes de la zona de supervisión, genera las señales correctoras necesarias para enviar a los dispositivos de campo (actuadores), gracias a los programas de control evaluados en cada momento.

LM (Logic Manager), HPM (High Process Manager), FSC (Fail Safe Controller): Son algunos de los elementos de control de proceso, cada uno de ellos especializado en un área de actividad.

UCN (Universal Control Network): Red de área local, proporciona el canal de comunicación para los distintos elementos de la zona. La capacidad de comunicación igual a igual permite compartir información entre los distintos elementos de la zona de control en la red, por lo que facilita la implementación de estrategias avanzadas de control de una forma coordinada.

Page 7: DCSLLL

2 Introducción

6

NIM (Network Interface Module): La UCN está conectada a la red de la zona de supervisión a través de un NIM. El NIM realiza la necesaria conversión entre las técnicas de transmisión y protocolos usados por las dos redes. Así se podrán intercambiar entre ambas redes datos, alarmas o mensajes en cualquiera de los dos sentidos.

• Supervisión de proceso (Process supervisión)

Es la interfaz con el personal, presenta información del funcionamiento del proceso y permite la modificación del funcionamiento de la zona de control.

Estación universal (Global User Station): Denominada anteriormente como consola de control, facilita al personal las herramientas necesarias para realizar su cometido.

• Gestión de la información (Management information)

Recopilación de información para análisis y estadísticas.

Es en la zona de control del proceso donde, tal y como se ha indicado, se encuentra el elemento en el que se basa este proyecto, el Logic Manager, conocido de forma simplificada con las iniciales LM.

2.2. Logic Manager (LM)

2.2.1. Descripción general El Logic Manager es lo que se conoce

como autómata programable.

El LM ejecuta funciones digitales y analógicas de control, proporcionando medios de control, comunicación, monitorización y uniones igual a igual con otros elementos de la zona de control de proceso.

Los elementos que forman un LM se distribuyen en racks de 19” de 14 ranuras.

El sistema LM recomendado está formado por un rack procesador simple o dos redundantes y un subsistema serie o paralelo de racks I/O.

Figura 2. El Logic Manager

Page 8: DCSLLL

2 Introducción

7

Figura 3. Configuración LM redundante con racks I/O serie.

2.2.1.1. Rack procesador El rack procesador se compone básicamente de un coprocesador conocido como Logic

Manager Module (LMM) que es la interfaz con la UCN, un Procesador programable (Control Processor) de alta velocidad que ejecuta el programa lógico y que contiene las zonas de memoria de registros y de programa, un Procesador I/O que maneja la información (datos) de los subsistemas de I/O ya sean serie (SLM – Serial Link Module) o paralelo (PLDM – Parallel Link Driver Module) y un Módulo de alimentación (PSM – Power Suply Module).

Figura 4. Composición de un rack procesador en configuración redundante

2.2.1.2. Rack I/O Un rack I/O standard contiene además de los modulos especiales de entradas y salidas

que proporcionan la unión con los dispositivos de campo, un Módulo de comunicación

Page 9: DCSLLL

2 Introducción

8

serie (SIOM) o paralelo (PIOM) con el rack procesador, un Módulo de diagnóstico avanzado (EDM – Enhanced Diagnostic Module) para solucionar problemas en el bus de I/O y un Módulo de alimentación (PSM – Power Suply Module).

Figura 5. Composición de un rack I/O serie

2.2.2. Descripción funcional El Procesador lee de forma rápida y continuada las entradas a procesar y ejecuta el

programa lógico de forma cíclica. El LM se programa mediante código ejecutable denominado lógica en escalera y se configura desde las estaciones universales.

Existe la posibilidad de elegir entre distintos modelos de procesador con sets de instrucciones y mapeados de memoria diferentes, para poder adaptarse a las necesidades particulares del proceso.

Operando en un ciclo de scan independiente del ciclo de ejecución de programa lógico del Procesador, el LMM maneja y procesa la información desde o hacia las tablas de datos de I/O. El LMM convierte estos datos a los tipos de datos de la UCN, realizando conversiones de unidades, manipulación de alarmas, informes de estados de diagnóstico y funciones de comunicación con la UCN.

A su vez, cambios realizados por los operadores en las estaciones universales son escritos inmediatamente en el Procesador. La base de datos del LMM se configura directamente desde las estaciones universales.

Figura 6. Arquitectura funcional de un LM

Page 10: DCSLLL

2 Introducción

9

La siguiente imagen resume todo lo expuesto hasta el momento:

Figura 7. Diagrama conceptual de los subsistemas de un LM

2.2.3. Características El Logic Manager reune las siguientes características:

• Gran variedad de módulos de Entrada/Salida también conocidos como E/S o I/O (Input/Output), para adaptar la diversidad de señales de los dispositivos de campo.

• Comunicación directa igual a igual y planificación de estrategias con otros elementos de la zona de control del proceso, iniciada por cualquiera de ellos.

• Total comunicación con operadores, ingenieros y personal de mantenimiento en la zona de supervisión del proceso a través de las estaciones universales de trabajo.

• Recuperación de bases de datos desde el módulo histórico (History Module).

• Rápida ejecución de programas lógicos.

• Amplia lógica digital, booleana o de enclavamiento. A modo de resumen dispone de:

- Instrucciones de contactos y bobinas.

- Instrucciones de bit simple.

- Instrucciones de temporizadores y contadores.

- Instrucciones de salto.

- Instrucciones de manipulación de datos.

Page 11: DCSLLL

2 Introducción

10

- Instrucciones de comparación de enteros.

- Instrucciones matemáticas.

- Instrucciones de operadores lógicos.

- Instrucciones de referencia de memoria.

- Instrucciones de conversión de datos.

- Instrucciones de secuenciador.

- Instrucciones de matrices.

- Instrucciones diversas.

• Facilidad de programación.

2.3. 623-60 MS-DOS Loader El paquete MS-DOS Loader es un conjunto de programas que, funcionando en entorno

MS-DOS, convierten cualquier PC en un dispositivo para programar y monitorizar cualquier sistema Logic Manager al conectar ambos equipos mediante un cable de comunicación serie.

La siguiente imagen es una captura del menú principal:

Figura 8. MS-DOS Loader - Menú principal

2.3.1. Descripción general

El programa MS-DOS Loader permite realizar las siguientes accciones:

1. Especificar la configuración del sistema (modelo de procesador, mapeado de memoria…).

2. Desarrollar el programa lógico evitando errores al impedir la utilización de instrucciones o direcciones no permitidas según la configuración introducida.

3. Transferir el programa desarrollado a la zona de memoria de programa del equipo Logic Manager.

4. Una vez el Logic Manager está ejecutando el programa lógico, presenta el estado y el valor de las direcciones de las tablas de memoria sobre las líneas del programa lógico, para que el usuario pueda supervisar la ejecución.

Page 12: DCSLLL

2 Introducción

11

2.3.2. Características Sus características principales son:

• Facilidad de uso: Diseñado para ser completamente manejado por menús, presenta una serie de ventanas de ayuda de tal forma que requiere mínimo aprendizaje.

• Integración de Programación y Documentación: Completa fusión entre programa lógico y documentación

• Programación “Stand-Alone”: Desarrollo del programa lógico sin necesidad de estar conectado al LM.

• Monitorización “On-Line”: Monitoriza el estado de ejecución del programa lógico tal y como es ejecutado.

• Modo de programación aumentado (ARMP): Edición del programa lógico mientras se está ejecutando.

• Funciones de búsqueda: Localiza contactos ya sea por número de línea, tipo de elemento, dirección o etiqueta de dirección.

• Completa documentación: Obtiene una impresión que incluye datos descriptivos tales como referencias cruzadas, direcciones no utilizadas, direcciones conflictivas y listados de todo tipo de documentación.

• Direcciones por etiquetas: Etiquetas de 7 caracteres para cada uno de los elementos lógicos, en vez de direcciones numéricas.

• Formato libre de edición de documentación: Hasta 20 líneas de 67 caracteres para comentarios de línea y de direcciones. Permitiendo la edición mientras se está en modo de monitorización.

• Potente función de búsqueda y reemplazo: Cambios de direcciones de un existente elemento lógico cada vez que dicho elemento es encontrado en el programa lógico.

• Funciones de edición de bloques: Permite al usuario redireccionar el elemento lógico en un bloque de lógica mientras está siendo cargado en memoria. Hasta ocho diferentes grupos de direcciones pueden ser reasignadas.

• Configuración flexible: Facilita especificar diferentes parámetros que configuran la forma de visualización y edición del programa lógico.

• Soporta todos los modelos de LM, en los modos de monitorización ON-Line y Stand-Alone.

• Funciones de visualización de datos: Monitoriza el valor de hasta 126 direcciones independientemente de su localización.

Page 13: DCSLLL

2 Introducción

12

2.3.3. Programa lógico – Código en escalera La siguiente imagen es una captura de la ventana de edición del programa lógico:

Figura 9. MS-DOS Loader - Ventana edición programa lógico

El siguiente párrafo es un pequeño trozo del informe que genera el programa DOS-Loader en el que, además del programa lógico, se incorporan datos de documentación (etiquetas, comentarios,…) y datos de ayuda al programador (líneas de programa en que aparecen las direcciones de salida - referencias cruzadas,…). !Line # 1185 ! ! Line # Cross-Ref of addr 6791 ! ! 1185 ,*1185 ,/1186 , 1187 , 1265 ! ! ! !MUY ALTO ! !NIV. SILO ! !EXTR. C ! ! HL20702 SET ! ! 303 6791 ! +--]\/[-------------+-----------------------------------------------------( )--+ ! ! ! ! (0 ) ! ! ! ! ! ! ! ! ! ! ! ! SET RESET ! ! ! 6791 6792 ! ! +---] [-------]/[---+ ! ! ! ! (1185 ) (1186 ) ! ! ! !Line # 1186 ! ! Line # Cross-Ref of addr 6792 ! ! /1185 , 1186 ,*1186 , 1187 ! ! ! !U2 ! ! ! ! ! ! ENTER2 RESET ! ! 894 6792 ! +--]/\[-------------+-----------------------------------------------------( )--+ ! ! ! ! (0 ) ! ! ! ! ! ! ! ! ! ! ! ! SET RESET ! ! ! 6791 6792 ! ! +---]/[-------] [---+ ! ! ! ! (1185 ) (1186 ) ! ! !

Page 14: DCSLLL

2 Introducción

13

2.4. Objetivos Tal y como se puede observar en las descripciones del equipo Logic Manager y del

programa MS-DOS Loader realizada en los apartados anteriores, se echa en falta un programa que en entorno Windows, facilite la visualización del programa lógico e incorpore una función de simulación.

Con esta herramienta se podría depurar el programa lógico sin necesidad de estar conectado al LM, reduciendo las horas de puesta en marcha de nuevos programas en un Logic Manager y eliminando el riesgo de parada de la unidad de fabricación controlada por el sistema, si existe un error en el programa en una zona crítica.

Por otro lado, existen instrucciones cuyo funcionamiento no queda claro en el manual de programación. Al necesitar despejar todas esas incógnitas en el desarrollo del simulador, futuros usuarios sólo necesitarán simularlas para comprobar el funcionamiento exacto, evitándose diseñar programas incorrectos por tener errores conceptuales.

2.4.1. Características Las características principales del programa a desarrollar deben de ser:

• Facilidad de uso: Ofrecer la potencia, facilidad de manejo y de aprendizaje que ofrece el entorno Windows.

• Integración de documentación y de programación: Mantener las mismas posibilidades de documentación que ofrece el programa Loader, mejorando las posibilidades de edición y búsqueda permitiendo el tratamiento de la documentación con la potencia de Microsoft Access.

• Facilidad de visualización: Presentación del programa lógico en un entorno gráfico.

• Potente herramienta de simulación: Función de simulación del programa lógico, permitiendo la ejecución en modo continuo y paso a paso.

• Módulo de ayuda a la simulación: Módulo de diseño de cronogramas de variables de entrada y de visualización de cronogramas en las variables de salida, para chequear el funcionamiento en modo continuo.

• Módulo de visualización de datos: Visualización en formato de tabla de las áreas de datos de I/O y registros.

• Adaptar el mapa de memoria y set de instrucciones en función del modelo de procesador seleccionado.

2.4.2. Exclusiones Se va a obviar la implementación de las siguientes características, por lo que se seguirá

utilizando el programa MS-DOS Loader para realizarlas:

• Transferencia de programas: Debido tanto a la falta de documentación del protocolo de comunicación entre el PC y el LM, como a la imposibilidad de realizar pruebas con un LM real para averiguarlo, pues un error en las mismas podría dañar el equipo, se ha decidido no implementar la función de cargar el programa desarrollado en el LM ni ninguna otra que implique comunicarse con el Logic Manager.

Page 15: DCSLLL

2 Introducción

14

• Edición del programa lógico: El MS-DOS Loader tiene funciones que facilitan el desarrollo de nuevos programas tales como supervisión de errores en la introducción de nuevas líneas, funciones de búsqueda y reemplazo… por lo que se ha dejado su implementación para un futuro proyecto.

Asimismo, a la hora de simular, se van a obviar principalmente las siguientes funciones:

• Soporte de todos los modelos de LM: Ya se ha comentado, que hay instrucciones cuyo funcionamiento no queda claro en el manual del programador. Como sólo se pueden realizar pruebas con un procesador modelo 620-35 y no se puede comprobar el funcionamiento de otros modelos, se ha decidido permitir la simulación de programas sólo cuando el sistema esté configurado con el modelo 620-35 ó 620-25 (modelo equivalente).

• Actualización de área de registros de estado del sistema: En la simulación no se actualizará el área destinada a los registros que contienen información de estado del sistema.

Page 16: DCSLLL

3 Funcionamiento del Logic Manager

15

3. Funcionamiento del Logic Manager En la introducción, se describen los componentes básicos de un Logic Manager y la

función que realizan:

• LMM (Logic Manager Module)

• CPM (Control Processor MODULE)

• Procesador E/S (I/O Link Processor)

• Módulos E/S (I/O Module)

Sin embargo, existen puntos que necesitan ser estudiados en profundidad.

3.1. Mapeado de memoria El LM tiene dos módulos que contienen la memoria con la que trabaja:

• Módulo de memoria de programa

• Módulo de memoria de registros (Register Module Tables)

3.1.1. Módulo de memoria de programa Este módulo almacena el programa de usuario.

Está formado por registros de 24 bits (3 Bytes) hasta un máximo de 32768 registros.

3.1.2. Módulo de memoria de registros Almacena la tabla de datos E/S del sistema. Esta tabla está dividida en tres:

• Tabla de estados E/S (I/O Status Table)

• Tabla de registros (Data Registers Table)

• Tabla de estados del sistema (System Status Table)

Figura 10. Mapa de memoria del modulo de memoria de registros.

3.1.2.1. Tabla de estados E/S Está formada por dos tablas de 1 bit superpuestas comenzando en la dirección 0.

• Tabla de estados de entrada (Input Status Table): Un máximo de 2048 registros están reservados para almacenar los estados de entradas reales.

System Status Table

Page 17: DCSLLL

3 Funcionamiento del Logic Manager

16

• Tabla de estados de salida (Output Status Table): De un máximo de 4096 registros, los 2048 primeros están disponibles para almacenar los estados de salidas reales o para almacenar variables binarias de uso interno. Los 2048 siguientes sólo pueden almacenar variables binarias de uso interno.

La tabla de estados de entrada solamente es actualizada por el procesador I/O.

La tabla de estados de salida es actualizada tanto por el procesador de control (resultados obtenidos por programa) como por el LMM (escritura desde el sistema de control distribuido).

Se debe destacar que para las direcciones 0-2047 en las que coexisten la tabla de estados de entrada y de salidas, el valor leído y por tanto el evaluado en el programa siempre es una OR de ambas tablas.

Las direcciones de entradas y salidas físicas de módulos E/S analógicos (rango 0-2047) son datos de 16 bits. Sin embargo, como se puede apreciar en la figura no tienen una tabla donde guardar el valor cíclicamente, pues son accedidas o modificadas por el programa en el momento en que se evalúa la instrucción correspondiente.

3.1.2.2. Tabla de registros Está formada por registros de 16 bits (más 1 bit adicional para el signo dependiendo del

modelo de LM escogido) hasta un máximo de 4096, comenzando en la dirección 4096.

Aquellos modelos que no utilizan un bit adicional para codificar el signo, utilizan Complemento a dos (Ca2).

La siguiente tabla indica qué formato numérico utiliza cada modelo de procesador:

Modelo Formato 620-06 16 (Ca2) 620-10O 16 (Ca2) 620-10N 16 (Ca2) 620-11 16 (Ca2) 620-12 16 (Ca2) 620-14 16 (Ca2) 620-15O 16 (Ca2) 620-15N 16 (Ca2) 620-16 16 (Ca2) 620-20 16 (Ca2) 620-25 16+1 620-30 16 (Ca2) 620-35 16+1 620-36 16 (Ca2)

Tabla 1. Formato de registros en función del modelo de procesador.

Los parámetros preset y acumulador de temporizadores y registros son almacenados en esta tabla junto con cualquier otro dato numérico que quiera ser memorizado.

En el caso de disponer de bit de signo, éste también puede ser utilizado para almacenar variables binarias de uso interno.

Page 18: DCSLLL

3 Funcionamiento del Logic Manager

17

La tabla de registros es actualizada tanto por el procesador de control (resultados obtenidos por programa) como por el LMM (escritura desde el sistema de control distribuido).

A partir de ahora, la memoria designada por la tabla de estados E/S y la tabla de registros se va a llamar memoria de usuario, mientras que la tabla de estados del sistema se va a llamar memoria de sistema.

3.1.2.3. Tabla de estados de sistema Está formada por registros de 8 bits hasta un máximo de 4096, comenzando por la

dirección 0.

Almacena información de diagnóstico del procesador pudiendo ser accedida por alguna de las instrucciones del programa de usuario, sólo en modo de lectura.

Está dividida en tres secciones:

• Diagnóstico del sistema

• Estado del hardware del sistema

• Identificación del sistema

3.2. Modos de funcionamiento El Logic Manager puede trabajar en cuatro modos de funcionamiento: RUN, DISABLE,

PROGRAM o RUN/PROGRAM.

Modo RUN: El procesador evalúa las líneas de código y actualiza las salidas con los resultados obtenidos.

Modo Disable: El procesador evalúa las líneas de código del mismo modo que el modo RUN, con la diferencia que las salidas no son actualizadas, manteniendo el último valor o reseteanse en función de la configuración del hardware.

Modo Program: El procesador deja de evaluar las líneas de código. Las salidas mantienen el último valor o se resetean en función de la configuración del hardware permitiendo la edición del programa y valores de registros temporizadores y contadores.

Modo RUN/PROGRAM: Este modo combina las prestaciones del modo RUN y PROGRAM. El procesador evalúa las líneas de código y actualiza las salidas con los resultados obtenidos permitiendo la edición del programa y valores de registros temporizadores y contadores.

3.3. Ciclo de ejecución de programa lógico (Ciclo de scan)

Cuando el sistema entra en modo RUN se realiza la siguiente secuencia:

Scan RetentivoControladorLogico en

modo RUN

ISSScan estado

entradas

Ejecuciónprograma lógico

Figura 11. Ciclo de scan del controlador lógico.

Page 19: DCSLLL

3 Funcionamiento del Logic Manager

18

1.- Scan retentivo: Se realiza una lectura previa del programa de usuario residente en memoria de programa en la que se evalúan todas las instrucciones y según los casos se actúa de una forma u otra:

• Salidas no retentivas: escriben un cero en la tabla de estados de salida.

• Salidas retentivas: recuperan el valor que tenían en el último scan antes de dejar el modo RUN (en el capítulo 4.2.3.2 Elementos de programa se explica como se almacena el valor anterior).

• Temporizadores con retardo a ON, retentivos y contadores: El acumulador se inicializa a cero.

• Temporizadores con retardo a OFF: El acumulador se inicializa con el valor del preset.

2.- Scan de los estados de las entradas (ISS - Input Status Scan): El procesador I/O escribe la tabla de estados de entrada con los valores de las direcciones de tarjetas de entradas.

3.- Ejecución programa lógico (scan): Se ejecuta el programa cargado en memoria hasta que se encuentra la instrucción de retorno al principio de programa (RBP) o la indicación de fin de programa. Cualquiera de ellas provoca volver al paso 2.

• El procesador utiliza la pila, para almacenar temporalmente los datos leídos que serán transferidos posteriormente a otros registros o serán utilizados como operadores en las instrucciones matemáticas, de comparación y conversión.

• A medida que el programa es ejecutado se evalúan y modifican los valores de las tablas de memoria y el procesador I/O actualiza simultáneamente las tarjetas de salidas.

• El tiempo que tarda en ejecutarse cada ciclo, es la suma del tiempo dedicado a realizar los pasos 2 y 3. La duración del paso 2 depende de la configuración de tarjetas E/S, mientras que la duración del paso 3 depende de las instrucciones que componen el programa a ejecutar.

Page 20: DCSLLL

3 Funcionamiento del Logic Manager

19

En las siguientes tablas se detallan los tiempos de ejecución de la mayoría de las instrucciones del set de instrucciones del Logic Manager.

Tabla 2. Tiempo de ejecución de cada instrucción (1/2)

Page 21: DCSLLL

3 Funcionamiento del Logic Manager

20

Tabla 3. Tiempo de ejecución de cada instrucción (2/2)

Page 22: DCSLLL

4 Interpretación MS-DOS Loader

21

4. Interpretación MS-DOS Loader Para poder simular el funcionamiento del LM, ha sido necesario interpretar los archivos

que utiliza para guardar los parámetros de configuración, los datos de documentación de soporte y el programa a ejecutar.

Toda esta información es visualizada y editada por medio del programa MS-DOS Loader, por lo que el método de decodificación consiste en realizar cambios y estudiar como afectan en los códigos de los archivos.

Las siguientes capturas, muestran la ventana de presentación del programa y el menú principal del MS-DOS Loader.

Figura 12. MS-DOS Loader - Pantalla de comienzo

Figura 13. MS-DOS Loader - Menú principal

Los siguientes capítulos se estructuran de acuerdo a éste menú. En cada uno de ellos se comenta cual es su función y como funciona.

Page 23: DCSLLL

4 Interpretación MS-DOS Loader

22

Nota importante: A medida que se ha ido estudiando el funcionamiento de las instrucciones y del sistema

del Logic Manager a lo largo del capítulo, han aparecido dudas que han podido ser resueltas mediante pruebas con un equipo real.

Sin embargo, en otras ocasiones, principalmente por falta de LM para poder realizar las pruebas, han aparecido dudas que no han podido ser resueltas. En estos casos, se ha destacado el párrafo que describe el problema y la decisión tomada para poder acabar el diseño, con el siguiente símbolo escrito al comienzo del mismo.

?

Page 24: DCSLLL

4 Interpretación MS-DOS Loader

23

4.1. F1 – 620 Loader / Monitor Se utiliza para comunicar con el Logic Manager. Si se trabaja sin el LM conectado y se

intenta conectar con él, transcurrido un tiempo, el programa informa de que no se puede realizar la conexión con el Controlador lógico del LM.

Como en el simulador se va a trabajar sin el LM conectado, la configuración de la comunicación serie no nos interesa.

4.2. F2 – 620 Stand alone loader (*.ldr) Se utiliza para acceder a la parte de edición del programa a ejecutar.

La ventana de edición del MS-DOS Loader trabaja principalmente con el fichero *.ldr, documento que contiene el programa de usuario codificado. Es por ello, que en este capítulo se va a estudiar la codificación de este documento.

Los archivos de documentación se estudiarán en el apartado que desarrolla la opción del menú principal encargada de los mismos (ver apartado 4.2.4).

Figura 14. MS-DOS Loader – F2 Pantalla edición Stand-Alone

La ventana de edición se divide en cinco partes:

• Línea superior de información.

Indica en la parte izquierda qué teclas apretar para acceder a la ayuda o volver al

menú principal y en la derecha, los campos de descripción de la etiqueta de la dirección de la instrucción de salida.

Al no ser necesaria en el simulador no necesita ser estudiada ni desarrollada.

• Zona central de edición y visualización.

Visualiza de una en una las líneas que componen el programa, permitiendo su edición. Se divide en una matriz de 5 filas x 10 columnas. Las 9 columnas primeras sirven para realizar las formaciones serie y/o paralelo de comandos. La última columna se reserva para introducir el comando de salida deseado.

Page 25: DCSLLL

4 Interpretación MS-DOS Loader

24

La captura superior muestra una de las celdas de la matriz de edición. La celda se

divide en tres partes: nombre de etiqueta de la dirección, número de dirección y símbolo del comando. Presionando la tecla ? una vez, aparecen todos los campos de la etiqueta de la dirección seleccionada por el puntero, si se pulsa otra vez, aparece el texto del comentario asociado.

• Menú de selección de comandos.

Permite al usuario seleccionar el comando que quiere introducir en la posición

marcada por el puntero dentro de la matriz de comandos.

Siendo el principal objetivo simular, es imprescindible estudiar la totalidad de comandos que compone el juego de instrucciones del Logic Manager.

• Menú de herramientas.

Permite al usuario acceder a herramientas que le permiten entre otras funciones:

imprimir el programa o los ficheros de documentación, buscar direcciones o comandos, listar el estado de variables.

Al no ser objetivo del proyecto perfeccionar las herramientas de edición, no es necesario estudiar ni desarrollar esta parte.

• Línea inferior de información.

Informa de la configuración del sistema: Modelo, memoria de programa total,

memoria de programa libre, modo de funcionamiento del LM, posición del selector de modo de funcionamiento del LM y estado de teclas de teclado “Ins”, “Del”, “Bloq Num” o “Bloq Mayus”.

Ésta línea sólo informa de la configuración seleccionada, es por ello que el estudio de los parámetros de configuración se realizará en el apartado que estudia la opción del menú principal encargada de ello (ver apartado 4.6).

4.2.1. Estructura básica del fichero *.ldr Para estudiar la codificación, tanto de este archivo como la del resto de archivos, se ha

utilizado un editor hexadecimal ya que facilita la edición de documentos que son combinación de formato hexadecimal y formato texto (ASCII).

La forma de detectar qué parte del fichero codificaba cada uno de los parámetros o comandos, ha sido ir cambiando estos de uno en uno hasta poder detectar quién era quién, y cómo se codificaba.

La siguiente tabla muestra los campos que, puestos uno detrás de otro, conforman el fichero *.ldr. En los siguientes apartados se estudia cada uno de ellos en detalle y por qué se ha llegado a determinar que la estructura es la aquí expuesta.

Page 26: DCSLLL

4 Interpretación MS-DOS Loader

25

Pos. Descripción Nº Bytes Formato Cabecera

1 Número modelo procesador 2 Hexa (LSB1 MSB2) 2 Tamaño memoria de programa

(Memory size) 2 Hexa (MSB LSB)

3 Tamaño memoria de registros(Register size)

2 Hexa (MSB LSB)

4 Tamaño memoria E/S real(Real I/O size)

2 Hexa (MSB LSB)

5 Número de elementos totales del programa

2 Hexa (LSB MSB)

6 Número de elementos totales del programa forzados

2 Hexa (LSB MSB)

7 Fecha 6 ASCII 8 Programador 26 ASCII 9 Título 96 ASCII

Cuerpo 10.1 Comienzo de nuevo bloque de

programa 1 Hexa (código h4C3)

10.2 Número de elementos del nuevo bloque de programa (máximo de h52)4

1 Hexa

10.3 Elementos del nuevo bloque de programa

3 x NElementos (pos. 10.2)

Hexa

10.4 Se repiten pos. 10.1, 10.2 y 10.3 hasta alcanzar el número de elementos totales del programa (pos. 5). Fin de programa 1 Hexa (código h4E o h53) 10.5 Según el modelo de LM corresponde un código u otro. Sólo si código h53 existen las siguientes posiciones.

Cola 11 Otros Varios Hexa

Tabla 4. Estructura del fichero *.ldr

4.2.2. Cabecera

4.2.2.1. Modelo del procesador Los siguientes subapartados muestran el fichero *.ldr en formato hexadecimal, para

cada uno de los modelos de LM configurables.

1 LSB es la abreviación de Least Significant Byte. Representa el código hexadecimal

que contiene los 8 bits bajos (posiciones 0 a 7) de una palabra de 16 bits. 2 MSB es la abreviación de Most Significant Byte. Representa el código hexadecimal

que contiene los 8 bits altos (posiciones 8 a 15) de una palabra de 16 bits. 3 Los números precedidos con h están expresados en formato hexadecimal. 4 La división de bloques no tiene en cuenta si la línea está a medias, simplemente cuenta

elementos.

Page 27: DCSLLL

4 Interpretación MS-DOS Loader

26

Para reducir las variaciones y así poder identificar parámetros se ha utilizado siempre la línea de programa que se muestra a continuación. 101 102 103 121 ├──] [─────] [──┬──] [─────────────────────────────────────────────────────( )── │ │ │ │ │ 104 105 │ ├──] [──┬──] [──┴ │ │ │ │ │ 106 │ ├──] [──┴

Hay que tener en cuenta, que al cambiar el modelo de LM, cambian también los valores posibles de tamaños de memoria, registros y E/S real al ser unos más potentes que otros. Es por ello que al principio de cada modelo se especifican los valores para cada uno de esos parámetros.

Modelo 620-06 Memory size: 2048, Register size: 256, Real I/O: 192

010000080001C0000900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C400794E

Modelo 620-10 OLD Memory size: 2048, Register size: 256, Real I/O: 256

00000008000100010900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C400794E

Modelo 620-10 NEW Memory size: 4096, Register size: 512, Real I/O: 512

00000010000200020900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C400794E

Modelo 620-11 Memory size: 8192, Register size: 4096, Real I/O: 256

06000020001000010900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C40079530000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Page 28: DCSLLL

4 Interpretación MS-DOS Loader

27

00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0032008000000B00000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000100000001000F7F0000077F0FFFF682149006820FF7788C8FF8F88C8FFFFC0B9F090F038FFF9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004E560000

Modelo 620-12

Memory size: 2048, Register size: 256, Real I/O: 256 0B000008000100010900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C4007953000000000000000000000000

Page 29: DCSLLL

4 Interpretación MS-DOS Loader

28

000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0032008000000B00000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000100000001000F7F0000077F0FFFF682149006820FF7788C8FF8F88C8FFFFC0B9F090F038FFF900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Page 30: DCSLLL

4 Interpretación MS-DOS Loader

29

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004E560000

Modelo 620-14 Memory size: 8192, Register size: 4096, Real I/O: 640

07000020001080020900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C4007953000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0032008000000B0000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Page 31: DCSLLL

4 Interpretación MS-DOS Loader

30

0000000008000100000001000F7F0000077F0FFFF682149006820FF7788C8FF8F88C8FFFFC0B9F090F038FFF9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004E560000

Modelo 620-15 OLD Memory size: 2048, Register size: 256, Real I/O: 256

01000008000100010900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C400794E

Modelo 620-15 NEW Memory size: 4096, Register size: 512, Real I/O: 512

01000010000200020900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C400794E

Modelo 620-16

Memory size: 8192, Register size: 4096, Real I/O: 2048 08000020001000080900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C400795300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Page 32: DCSLLL

4 Interpretación MS-DOS Loader

31

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0032008000000B00000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000100000001000F7F0000077F0FFFF682149006820FF7788C8FF8F88C8FFFFC0B9F090F038FFF9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004E560000

Page 33: DCSLLL

4 Interpretación MS-DOS Loader

32

Modelo 620-20 Memory size: 8192, Register size: 2048, Real I/O: 512

02000020000800020900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C400794E

Modelo 620-25 Memory size: 32768, Register size: 4096, Real I/O: 2048

04000080001000080900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C400794E

Modelo 620-30 Memory size: 24576, Register size: 4096, Real I/O: 2048

03000060001000080900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C400794E

Modelo 620-35 Memory size: 32768, Register size: 4096, Real I/O: 2048

05000080001000080900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C400794E

Modelo 620-36 Memory size: 32768, Register size: 4096, Real I/O: 2048

0A000080001000080900000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09C90065C80066CA0068C9006AC37FFFC80069C37FFFC80067C4007953000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Page 34: DCSLLL

4 Interpretación MS-DOS Loader

33

000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030353037303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0032008000000B00000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000100000001000F7F0000077F0FFFF682149006820FF7788C8FF8F88C8FFFFC0B9F090F038FFF9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004E560000

Page 35: DCSLLL

4 Interpretación MS-DOS Loader

34

Resumen Se concluye que el modelo de procesador para todos los valores que puede tener se

codifica de la forma expuesta en la tabla siguiente.

Modelo Código Hexa Código Decimal 620-06 h01 1 620-10O h00 0 620-10N h00 0 620-11 h06 6 620-12 h0B 11 620-14 h07 7 620-15O h01 1 620-15N h01 1 620-16 h08 8 620-20 h02 2 620-25 h04 4 620-30 h03 3 620-35 h05 5 620-36 h0A 10

Tabla 5. Codificación del parámetro modelo de procesador

4.2.2.2. Tamaño de memoria de programa (Memory size) Para determinar los códigos que codifican el parámetro “tamaño de memoria de

programa” se ha ido variando el mismo, y se han sombreado las diferencias en los códigos resultantes.

Modelo:620-35, “Memory size”: 32768, “Register size”: 4096, “Real I/O”: 2048 05000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Modelo:620-35, “Memory size”: 30720, “Register size”: 4096, “Real I/O”: 2048 05000078001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Modelo:620-35, “Memory size”: 28672, “Register size”: 4096, “Real I/O”: 2048 05000070001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Modelo:620-35, “Memory size”: 2048, “Register size”: 4096, “Real I/O”: 2048 05000008001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Modelo:620-15N, “Memory size”: 512, “Register size”: 256, “Real I/O”: 256 01000002000100010200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Page 36: DCSLLL

4 Interpretación MS-DOS Loader

35

Se concluye que el valor “memory size” para todos los valores que puede tener se codifica de la siguiente forma:

Valor Codigo Hexa Codigo Decimal 512 h02 2 1024 h04 4 2048 h08 8 4096 h10 16 6144 h18 24 8192 h20 32 10240 h28 40 12288 h30 48 14336 h38 56 16384 h40 64 18432 h48 72 20480 h50 80 22528 h58 88 24576 h60 96 26624 h68 104 28672 h70 112 30720 h78 120 32768 h80 128

Tabla 6. Codificación del parámetro "Memory size"

4.2.2.3. Tamaño de memoria de registros (Register size) Siguiendo el procedimiento del apartado anterior:

Modelo:620-35, “Memory size”: 32768, “Register size”: 4096, “Real I/O”: 2048 05000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Modelo:620-35, “Memory size”: 32768, “Register size”: 2048, “Real I/O”: 2048 05000080000800080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Modelo:620-15N, “Memory size”: 512, “Register size”: 256, “Real I/O”: 256 01000002000100010200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Se concluye que el valor “register size” para todos los valores que puede tener se codifica de la siguiente forma:

Valor Codigo Hexa 256 h01 512 h02 2048 h08 4096 h10

Tabla 7. Codificación del parámetro "Register size"

Page 37: DCSLLL

4 Interpretación MS-DOS Loader

36

4.2.2.4. Tamaño de memoria E/S real (Real I/O size) Modelo:620-35, “Memory size”: 32768, “Register size”: 4096, “Real I/O”: 2048

05000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Modelo:620-35, “Memory size”: 32768, “Register size”: 2048, “Real I/O”: 1024 05000080001000040200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Modelo:620-35, “Memory size”: 32768, “Register size”: 2048, “Real I/O”: 512 05000080001000020200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Modelo:620-06, “Memory size”: 2048, “Register size”: 256, “Real I/O”: 192 010000080001C0000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Se concluye que el valor “real I/O size” para todos los valores que puede tener se codifica de la siguiente forma.

Valor Codigo Hexa 192 0 (C000h1) 256 01 512 02 1024 04 2048 08

Tabla 8. Codificación parámetro "Real I/O size"

4.2.2.5. Número de elementos totales del programa Modelo: 620-35, “Memory size”: 32768, “Register size”: 4096, “Real I/O”: 2048

SALIDA 1 2 ───] [─────────────────────────────────────────────────────────────────────( )── 0500008000100008 0200 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C80001C400024E

Insertando ahora antes de la línea 1, la línea siguiente, el programa queda: EEEEEEE 3 4 ───] [─────────────────────────────────────────────────────────────────────( )── 0500008000100008 0400 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04C80003C40004C80001C400024E

Se observa que al ir cambiando las líneas de código, cambia el número codificado, y que además crece cuanto más código hay. Con este detalle y con lo que se describe en el

1 Para codificar 192, no se utiliza el código h0000 si no el hC000.

Page 38: DCSLLL

4 Interpretación MS-DOS Loader

37

apartado 4.2.3 Cuerpo, se concluye que el número codificado (LSB MSB) contiene el número de elementos totales del programa.

4.2.2.6. Número de elementos totales del programa forzados El LM permite forzar alguna de sus instrucciones o elementos.

Según las pruebas realizadas y las notas del manual de usuario, los elementos que pueden ser forzados son:

INSTRUCCIÓN SIMBOLOInstrucciones de contactos y bobinasContacto normalmente abierto -] [-Contacto normalmente abierto - bifurcación anterior en TContacto normalmente abierto - bifurcación anterior en XContacto normalmente cerrado -]/[-Contacto normalmente cerrado - bifurcación anterior en TContacto normalmente cerrado - bifurcación anterior en XContacto transicional a ON -]/\]-Contacto transicional a OFF -]\/[-Salida no retentiva -( )-Salida retentiva -(R)-salida latch -(L)-Salida unlatch -(U)-Instrucciones de bit simpleLectura de bit -]BR[-Escribir bit -(BW)-Instrucciones de temporizadores y contadoresTemporizador retardo a ON 1 segundo -(TON)-Temporizador retardo a ON 0.1 segundos -(TON)-Temporizador retardo a ON 0.01 segundos -(TON)-Temporizador retardo a OFF 1 segundo -(TOFF)-Temporizador retardo a OFF 0.1 segundos -(TOFF)-Temporizador retardo a OFF 0.01 segundos -(TOFF)-Instrucciones de saltoNo salto con retención NSKRNo salto con desactivación NSKDInstrucciones de manipulación de datosEscritura de datos -(S2)-Instrucciones de comparación de enterosPrueba de cero -]Z[-Instrucciones de referencia de memoriaNo salto con retención (8192-8447) NSKRNo salto con retención (8448) NSKRRetorno a principio de programa RBP

Tabla 9. Instrucciones que pueden ser forzadas

La función de forzado permite sustituir el valor que tendría que tomar el elemento en función de la lógica, por el valor que desee el usuario.

Elementos digitales:

• Forzado a ON: Valor digital “1”. La secuencia lógica se cumple.

• Forzado a OFF: Valor digital “0”. La secuencia lógica no se cumple.

Elemento “escritura de datos”:

• Valor entero deseado.

El LM muestra un elemento forzado a ON escribiendo las letras FC debajo del gráfico del elemento, además de marcarlo en rojo.

Page 39: DCSLLL

4 Interpretación MS-DOS Loader

38

SALIDA 1 2 ───] [─────────────────────────────────────────────────────────────────────( )── FC 0500008000100008 0200 0100 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02F80001C400024E

El LM muestra un elemento forzado a OFF escribiendo las letras FO debajo del gráfico del elemento. SALIDA 1 2 ───] [─────────────────────────────────────────────────────────────────────( )── FO FO 0500008000100008 0200 0200 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02D80001D400024E

Se observa que al ir cambiando el número de elementos forzados, cambia el número codificado. Se concluye que el número codificado (LSB MSB) contiene el número de elementos totales del programa forzados.

Una peculiaridad del LM es que el forzado sólo afecta al elemento forzado, y no a la dirección que tiene ese elemento. Esto implica que, para forzar una dirección es necesario forzar todos los elementos que aparecen en el programa que trabajan con ella.

Esta característica implica que la información del forzado está relacionada con el elemento, y no con la dirección. Esto coincide con la estructura expuesta en el apartado 3.1.2 Módulo de memoria de registros, ya que lo contrario implicaría que las tablas de estados E/S incorporasen un bit de estado de forzado para cada dirección.

4.2.2.7. Fecha Es fácil identificar este campo pues está codificado en ASCII, de tal forma que el texto

introducido en el MS-DOS Loader es el que se visualiza directamente en un editor de texto, por lo que contando el número de caracteres editables en el campo “Fecha” del MS-DOS Loader se obtiene que tiene una longitud de 6 Bytes.

4.2.2.8. Programador Es fácil identificar este campo, pues está codificado en ASCII, de tal forma que el texto

introducido en el MS-DOS Loader es el que se visualiza directamente en un editor de texto, por lo que contando el número de caracteres editables en el campo “Programador” del MS-DOS Loader se obtiene que tiene una longitud de 26 Bytes.

4.2.2.9. Título

Es fácil identificar este campo, pues está codificado en ASCII, de tal forma que el texto introducido en el MS-DOS Loader es el que se visualiza directamente en un editor de texto, por lo que contando el número de caracteres editables en el campo “Título” del MS-DOS Loader se obtiene que tiene una longitud de 96 Bytes.

4.2.3. Cuerpo

En este apartado se estudia la codificación de la parte de programa que contiene las líneas lógicas.

Page 40: DCSLLL

4 Interpretación MS-DOS Loader

39

4.2.3.1. Bloques de programa Tal y como ya se ha visto en el apartado 4.2.2.5, el programa se compone de líneas que,

a su vez, se componen de elementos.

Modelo: 620-35, “Memory size”: 32768, “Register size”: 4096, “Real I/O”: 2048 SALIDA 1 2 ───] [─────────────────────────────────────────────────────────────────────( )── 0500008000100008 0200 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 4C02 C80001 C40002 4E

En el ejemplo anterior y en los que se han expuesto hasta ahora se aprecia que la parte que codifica el programa empieza siempre con el código h4C. Este código es seguido por un número que coincide con el número total de elementos del programa, expresado con 1 Byte y no 4.

Aumentando el número de líneas se observa que ambos números coinciden hasta que el número total de elementos supera la cifra 82 (h52). En ese momento, vuelve a aparecer el código 4C seguido del número de elementos que faltan hasta alcanzar el número total de elementos, a no ser que vuelva a ser mayor de 82 con lo que vuelve a crearse otro bloque y así sucesivamente.

En el mismo ejemplo, se aprecia que eliminando el Byte final (h4E), el número de Bytes restantes, es el número de elementos del bloque x 3. Esto implica que cada elemento se codifica con 3 Bytes.

Esta forma de dividir el programa en bloques de elementos no tiene en cuenta si una línea de programa está dividida en dos bloques.

4.2.3.2. Elementos de programa Se va a estudiar en detalle la codificación de un elemento para extraer las características

comunes.

Se ha elegido como elemento de estudio la instrucción “contacto normalmente abierto” por ser la más común en los programas.

SALIDA 1 2 ───] [─────────────────────────────────────────────────────────────────────( )── 05000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 C80001 400024E

El número decimal 1 equivale al hexadecimal h0001. Así se puede deducir que por ejemplo, el contacto normalmente abierto se identifica con el código hC8 seguido de la dirección en hexadecimal (MSB LSB).

Por lo que los 3 Bytes que componen cada elemento son:

1 Byte Codigo del elemento (Opcode).

2 Bytes Parámetro del elemento, generalmente número de dirección codificada en hexadecimal (MSB LSB).

Page 41: DCSLLL

4 Interpretación MS-DOS Loader

40

Los elementos de programa en la memoria de programa Tal y como ya se ha comentado, en la línea de información de la ventana de edición del

programa de usuario del MS-DOS Loader, existe un campo que informa de la memoria de programa libre.

Estudiando cómo se modifica este campo al añadir cada una de las instrucciones se puede llegar a concluir cómo se almacena el programa en la memoria de programa del LM.

Aunque no tiene porqué coincidir la forma de almacenar el programa en memoria del LM, con la forma en que se almacena en el archivo *.ldr, los siguientes puntos hacen pensar que en la mayoría de los casos es idéntica:

• El tamaño del elemento de 3 Bytes (24 bits) coincide con el tamaño de los registros de la memoria de programa.

• Al introducir nuevas líneas de programa, el número de registros libres de la memoria de programa, se reduce en igual cuantía que el número de elementos que conforman la línea.

Sabiendo esto, se pueden concluir ciertas cosas del funcionamiento del LM que no se determinan en la documentación disponible.

Almacenando información de estado en el Opcode Si se fuerza a ON el elemento en estudio:

SALIDA 1 2 ───] [─────────────────────────────────────────────────────────────────────( )── FC 05000080001000080200010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 F80001 C400024E

Se observa que el código del contacto normalmente abierto pasa de hC8 a hF8.

Si se fuerza a OFF el elemento en estudio: SALIDA 1 2 ───] [─────────────────────────────────────────────────────────────────────( )── FO FO 05000080001000080200020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 D80001 D400024E

Se observa que el código del contacto normalmente abierto pasa de hC8 a hD8.

De esto se comprueba lo que ya se intuía en el apartado 4.2.2.6 Número de elementos totales del programa forzados, el valor de forzado de un elemento no se guarda en la tabla de estados E/S o en otra tabla independiente, sino en el propio código del elemento.

Si se evalúan los cambios que sufre el opcode de un elemento no forzado, forzado a ON y forzado a OFF, se concluye que de los 8 bits que componen el código, los llamados bits históricos (nombre en que se refieren a ellos en las pocas referencias en que aparecen en el manual de usuario) son los que ocupan posiciones 4 y 5 (posiciones 20 y 21 si se tienen en cuenta los 24 bits que codifican el elemento).

• bit 20: indica con un “1” si el elemento está forzado.

• bit 21: indica, en el caso de bit 20 a “1”, el valor que debe de sustituir al que tiene la dirección.

Page 42: DCSLLL

4 Interpretación MS-DOS Loader

41

Al pasar a modo RUN, se realiza un scan retentivo (lectura inicial del programa residente en memoria) (ver apartado 3.3 Ciclo de ejecución de programa lógico (Ciclo de scan)), en el que las salidas retentivas eran evaluadas y se actualizaba la tabla de estados de salida con el último valor que tenían antes de dejar el modo RUN la última vez.

Viendo lo aquí expuesto, se concluye que estos mismos bits históricos son utilizados para almacenar el valor previo de dichos elementos en el scan anterior. Así podrán ser utilizados tanto para restaurar bobinas retentivas como detectar flancos ascendentes y descendentes.

Como el bit 20 es el que indica si el elemento ha sido forzado, debe de ser el bit 21 quien contenga la información del valor en el scan anterior.

Opcode Parámetro

23-22 21 20 19-16 15-8 7-0

Figura 15. Estructura genérica de un elemento

Estado de forzado Valor ciclo anterior o valor de forzado

Page 43: DCSLLL

4 Interpretación MS-DOS Loader

42

Así, los elementos que permiten ser forzados, pueden presentar los siguientes opcodes:

INSTRUCCIÓN SIMBOLO CODIGOFORZADO

A OFFFORZADO

A ONInstrucciones de contactos y bobinasContacto normalmente abierto -] [- C8 D8 F8Contacto normalmente abierto - bifurcación anterior en T C9 D9 F9Contacto normalmente abierto - bifurcación anterior en X CA DA FAContacto normalmente cerrado -]/[- CC DC FCContacto normalmente cerrado - bifurcación anterior en T CD DD FDContacto normalmente cerrado - bifurcación anterior en X CE DE FEContacto transicional a ON -]/\]- 43 53 73Contacto transicional a OFF -]\/[- 4B 5B 7BSalida no retentiva -( )- C4 D4 F4Salida retentiva -(R)- C5 D5 F5salida latch -(L)- C6 D6 F6Salida unlatch -(U)- C7 D7 F7Instrucciones de bit simpleLectura de bit -]BR[- 03 13 33Escribir bit -(BW)- 85 95 B5Instrucciones de temporizadores y contadoresTemporizador retardo a ON 1 segundo -(TON)- 4A Nota 1Temporizador retardo a ON 0.1 segundos -(TON)- 49 Nota 1Temporizador retardo a ON 0.01 segundos -(TON)- 68 Nota 1Temporizador retardo a OFF 1 segundo -(TOFF)- 42 Nota 1Temporizador retardo a OFF 0.1 segundos -(TOFF)- 41 Nota 1Temporizador retardo a OFF 0.01 segundos -(TOFF)- 60 Nota 1Instrucciones de saltoNo salto con retención NSKR 46 56 76No salto con desactivación NSKD 47 57 77Instrucciones de manipulación de datosEscritura de datos -(S2)- 07 37 (Nota 2) 37Instrucciones de comparación de enterosPrueba de cero -]Z[- 8D 9D BDInstrucciones de referencia de memoriaNo salto con retención (8192-8447) NSKR 46 56 76No salto con retención (8448) NSKR 46 56 76Retorno a principio de programa RBP 05 15 35

Nota 1.- Fuerza la salida no retentiva asociada (opcode hC4)Nota 2.- Excepcionalmente el forzado a OFF se comporta como el forzado a ON, consultar el apartado que estudia esta instrucción

Tabla 10. Opcode de instrucciones forzadas

Page 44: DCSLLL

4 Interpretación MS-DOS Loader

43

4.2.3.3. Juego de instrucciones Lo primero es saber qué comandos componen el juego de instrucciones, para determinar

como se codifica cada uno de ellos.

Según el menú del MS-DOS Loader El menú de selección de comandos se divide en submenús que agrupan los comandos

según su funcionalidad.

Estos submenús se pueden apreciar en las siguientes capturas.

Figura 16. MS-DOS Loader – F2 F1 Entradas binarias

Figura 17. MS-DOS Loader – F2 F2 Salidas binarias

Figura 18. MS-DOS Loader – F2 F3 Entradas/salidas enteras

Figura 19. MS-DOS Loader – F2 F4 Manejo de la pila

Figura 20. MS-DOS Loader – F2 F5 Saltos

Figura 21. MS-DOS Loader – F2 F6 Temporizadores/Contadores

Figura 22. MS-DOS Loader – F2 F7 Secuenciador

Figura 23. MS-DOS Loader – F2 F8 Subrutinas

Page 45: DCSLLL

4 Interpretación MS-DOS Loader

44

Figura 24. MS-DOS Loader – F2 F9 Operadores

Figura 25. MS-DOS Loader - F2 F9 F6 Operadores de conversión tipo de datos

Figura 26. MS-DOS Loader - F2 F9 F7 Operadores matemáticos

Figura 27. MS-DOS Loader – F2 F9 F8 Operadores lógicos

Figura 28. MS-DOS Loader – F2 F10 Matrices

Según el manual del programador En vez de seguir la secuencia reflejada en las imágenes superiores, se ha considerado

tratarlos y agruparlos de la misma manera en que se enumeran en el manual del programador “Guía de programación del MS-DOS loader”, ya que este documento es el que se ha utilizado principalmente para realizar el estudio de cada comando.

Hay que tener en cuenta que el juego de instrucciones varía en función del modelo de procesador elegido.

En la tabla siguiente se muestra el juego de instrucciones completo, el orden en que se va a desarrollar y qué instrucciones soporta cada modelo.

Page 46: DCSLLL

4 Interpretación MS-DOS Loader

45

INSTRUCCIÓN SIMBOLO620-06620-15 620-10

620-11620-12620-14

620-1631620-1633

620-36620-25620-35

Instrucciones de contactos y bobinasContacto normalmente abierto -] [- X X X XContacto normalmente abierto - bifurcación anterior en T X X X XContacto normalmente abierto - bifurcación anterior en X X X X XContacto normalmente cerrado -]/[- X X X XContacto normalmente cerrado - bifurcación anterior en T X X X XContacto normalmente cerrado - bifurcación anterior en X X X X XContacto transicional a ON -]/\]- X X X XContacto transicional a OFF -]\/[- X X X XSalida no retentiva -( )- X X X XSalida retentiva -(R)- X X X Xsalida latch -(L)- X X X XSalida unlatch -(U)- X X X XInstrucciones de bit simpleLectura de bit -]BR[- XEscribir bit -(BW)- XRamas serie y paraleloBifurcación descendente en T X X X XBifurcación descendente en X X X X XBifurcación ascendente en T X X X XInstrucciones de temporizadores y contadoresTemporizador retardo a ON 1 segundo -(TON)- X X X XTemporizador retardo a ON 0.1 segundos -(TON)- X X X XTemporizador retardo a ON 0.01 segundos -(TON)- X XTemporizador retardo a OFF 1 segundo -(TOFF)- X X X XTemporizador retardo a OFF 0.1 segundos -(TOFF)- X X X XTemporizador retardo a OFF 0.01 segundos -(TOFF)- X XTemporizador retentivo 1 segundo -(TON)- X X X XTemporizador retentivo 0.1 segundos -(TON)- X X X XTemporizador retentivo 0.01 segundos -(TON)- XContador CTU/CTD X X X XParametros contador/temporizador X X X XInstrucciones de saltoNo salto con retención NSKR X X X XNo salto con desactivación NSKD X X X XFin de salto EOS X X X XInstrucciones de manipulación de datosLectura de datos (Bring in) -[B2]- X X XLectura de datos indirecta -<B2>- X X XLectura de datos en coma flotante -[FP]- XEscritura de datos -(S2)- X X XEscritura de datos indirecta -(I2)- X X XEscritura de datos en coma flotante -(FP)- XConstante -[K2]- X X XConstante en coma flotante (primera palabra) -[FPK]- XConstante en coma flotante (segunda palabra) -[FPK]- XLectura de datos 1-8 bloques de 16 bits zona I/O (PULL) -[PUL]- X X XLectura de datos 1-8 bloques de 16 bits zona Reg. (PULL) -[PUL]- X X XEscritura de datos 1-8 bloques de 16 bits zona I/O (PUSH) -(PSH)- X X XEscritura de datos 1-8 bloques de 16 bits zona Reg. (PUSH) -(PSH)- X X XLectura de datos tabla estados del sistema (PULS) -[PULS]- XInstrucciones de comparación de enterosIgual que -]=[- X X XMenor que -]<[- X X XMayor que -]>[- X X XPrueba de cero -]Z[- X X XInstrucciones matemáticasSuma -[+]- X X XSuma con dirección de error [+] X X X

Tabla 29. Juego instrucciones según modelo de procesador (1/2)

Page 47: DCSLLL

4 Interpretación MS-DOS Loader

46

Instrucciones matemáticasSuma -[+]- X X XSuma con dirección de error -[+]- X X XResta -[-]- X X XResta con dirección de error -[-]- X X XMultiplicación -[*]- X X XMultiplicación con dirección de error -[*]- X X XDivisión -[/]- X X XDivisión con dirección de error -[/]- X X XInstrucciones de operadores lógicosAND bloque de 16 bits -[&]- XOR bloque de 16 bits -[OR]- XXOR bloque de 16 bits -[XOR]- XInstrucciones de referencia de memoriaNo salto con retención (8192-8447) NSKR X X X XNo salto con retención (8448) NSKR X X XSalto a subrutina JSR X XSubrutina SUB X XRetorno a subrutina RTS X XRetorno a principio de programa RBP X X X XInstrucciones de conversión de datosConversión binario a BCD -[BCD]- XConversión binario a BCD con dirección de error -[BCD]- XConversión BCD a binario -[BIN]- XConversión BCD a binario con dirección de error -[BIN]- XConversión entero a coma flotante -[FLT]- XConversión entero a coma flotante con dirección de error -[FLT]- XConversión coma flotante a entero -[INT]- XConversión coma flotante a entero con dirección de error -[INT]- XValor absoluto -[ABS]- XValor absoluto con dirección de error -[ABS]- XRaiz cuadrada -[SQRT]- XRaiz cuadrada con dirección de error -[SQRT]- XComplemento a dos bloque de 16 bits (Negacion) -[NEG]- XInversión de bits bloque de 16 bits (Not) -[NOT]- XInstrucciones de secuenciadorSecuenciador X X X XCarga secuenciador -(LS2)- X X XDescarga secuenciador -(US2)- X XInstrucciones de matricesMatriz de puesta a cero y de puesta a uno X XMover matriz X XInvertir matriz X XMatriz OR X XMatriz OR exclusiva X XMatriz AND X XComparar matriz X XInstrucciones diversasRetardo (DLA) -[DLA]- XOperación nula NOP X X X XOperación nula NOPExploración estado entradas ISS X X X XInstrucciones no descritas en el manualInversor lógico -]o[- XCodigos de controlComienzo de bloque de códigoFin de programa (corto)Fin de programa (largo)Marcador/comentario de línea

Tabla 30. Juego instrucciones según modelo de procesador (2/2)

Page 48: DCSLLL

4 Interpretación MS-DOS Loader

47

4.2.3.4. Instrucciones de contactos y bobinas Permiten acceder a direcciones binarias.

Contacto normalmente abierto ENTRADA SALIDA 1001 1 ───] [─────────────────────────────────────────────────────────────────────(R)── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 C803E9 C50001530000000000000000000000

Si la dirección especificada tiene un 1 y la lógica precedente es 1, permite seguir la secuencia en las instrucciones siguientes.

Puede ser forzado.

Codificación

El número decimal 1001 equivale al hexadecimal h03E9. Así se puede deducir que por ejemplo, el contacto normalmente abierto se identifica con el código hC8 seguido de la dirección en hexadecimal (MSB LSB).

Se observa que se codifica con tres Bytes, como era de esperar:

1 Byte Opcode (hC8).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (hF8).

Forzado a OFF Opcode (hD8)

Contacto normalmente cerrado ENTRADA SALIDA 1001 1 ───]/[─────────────────────────────────────────────────────────────────────( )── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 CC03E9 C40001530000000000000000000000

Si la dirección especificada tiene un 0 y la lógica precedente es 1, permite seguir la secuencia en las instrucciones siguientes.

Puede ser forzado.

Codificación

Se codifica con tres Bytes:

1 Byte Opcode (hCC).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (hFC).

Forzado a OFF Opcode (hDC)

Page 49: DCSLLL

4 Interpretación MS-DOS Loader

48

Contacto transicional a ON ENTRADA SALIDA 1001 1 ──]/\[─────────────────────────────────────────────────────────────────────(L)── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 4303E9 C60001530000000000000000000000

Si existe una transición 0 a 1 y la lógica precedente es 1, permite seguir la secuencia en las instrucciones siguientes.

Puede ser forzado.

Codificación

Se codifica con tres Bytes:

1 Byte Opcode (h43).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (h73).

Forzado a OFF Opcode (h53).

Según se ha comentado en el apartado 4.2.3.2 Elementos de programa, utiliza el bit 21 del registro en memoria de programa para guardar el estado en el ciclo anterior y así poder detectar los flancos. Debido a esta característica el MS-DOS Loader también reconoce el código h63 como contacto transicional a ON.

Esta característica coincide con los resultados de las pruebas realizadas sobre un programa ejecutado en el LM. Se obtuvo que una misma dirección podía activar un contacto transicional a ON y otro a OFF en distintas líneas de un mismo scan, si entre ellas se realizaba la modificación de la dirección en la secuencia adecuada.

Se demuestra así que no se realiza una copia de los valores de la tabla de estados E/S al comienzo de scan para detectar el flanco, sino que el histórico está relacionado con el elemento.

Contacto transicional a OFF ENTRADA SALIDA 1001 1 ──]\/[─────────────────────────────────────────────────────────────────────(U)── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 4B03E9 C70001530000000000000000000000

Si existe una transición 1 a 0 y la lógica precedente es 1, permite seguir la secuencia en las instrucciones siguientes.

Puede ser forzado.

Codificación

Se codifica con tres Bytes:

1 Byte Opcode (h4b).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Al ser forzado:

Page 50: DCSLLL

4 Interpretación MS-DOS Loader

49

Forzado a ON Opcode (h7B).

Forzado a OFF Opcode (h5B).

Según se ha comentado en el apartado 4.2.3.2 Elementos de programa, utiliza el bit 21 del registro en memoria de programa para guardar el estado en el ciclo anterior y así poder detectar los flancos. Debido a esta característica el MS-DOS Loader también reconoce el código h6B como contacto transicional a ON.

Esta característica coincide con los resultados de las pruebas realizadas sobre un programa ejecutado en el LM. Se obtuvo que una misma dirección podía activar un contacto transicional a ON y otro a OFF en distintas líneas de un mismo scan, si entre ellas se realizaba la modificación de la dirección en la secuencia adecuada.

Se demuestra así que no se realiza una copia de los valores de la tabla de estados E/S al comienzo de scan para detectar el flaco, sino que el histórico está relacionado con el elemento.

Bobina no retentiva ENTRADA SALIDA 1001 1 ───]/[─────────────────────────────────────────────────────────────────────( )── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02CC03E9 C40001 530000000000000000000000

La dirección especificada cambia a 1 si la lógica precedente es 1, o a 0 si la lógica precedente es 0.

Puede ser forzado.

Al comenzar la ejecución, durante el scan retentivo se ponen a 0.

Al estar dentro del bloque de salto de una instrucción NSKD, durante el primer ciclo se ponen a 0.

Al estar dentro del bloque de salto de una instrucción NSKR o NSKD en posteriores ciclos al primero, mantienen el valor, por lo que si son modificadas en líneas no afectadas por el salto (situación anómala pues se intenta evitar utilizar la misma dirección como salida en líneas diferentes) o por edición del usuario, no vuelven a resetearse.

Si el elemento está forzado y está dentro de un bloque de salto NSKR activo, el valor forzado no se escribe, sin embargo tampoco se reseteará en caso de estar dentro de un bloque de salto NSKD activo (primer ciclo).

Codificación

Se codifica con tres Bytes:

1 Byte Opcode (hC4).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (hF4).

Forzado a OFF Opcode (hD4).

Page 51: DCSLLL

4 Interpretación MS-DOS Loader

50

Bobina retentiva ENTRADA SALIDA 1001 1 ───] [─────────────────────────────────────────────────────────────────────(R)── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02C803E9 C50001 530000000000000000000000

La dirección especificada cambia a 1 si la lógica precedente es 1, o a 0 si la lógica precedente es 0.

Puede ser forzado.

Al comenzar la ejecución, durante el scan retentivo recuperan el último estado anterior al corte de alimentación.

Al estar dentro del bloque de salto de una instrucción NSKD, durante el primer ciclo se ponen a 0.

Al estar dentro del bloque de salto de una instrucción NSKR o NSKD en posteriores ciclos al primero, mantienen el valor, por lo que si son modificadas en líneas no afectadas por el salto (situación anómala pues se intenta evitar utilizar la misma dirección como salida en líneas diferentes) o por edición el usuario, no vuelven a resetearse.

Si el elemento está forzado y está dentro de un bloque de salto NSKR activo, el valor forzado no se escribe, sin embargo tampoco se reseteará en caso de estar dentro de un bloque de salto NSKD activo (primer ciclo).

Codificación

Se codifica con tres Bytes:

1 Byte Opcode (hC5).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (hF5).

Forzado a OFF Opcode (hD5).

Utiliza el bit 21 del registro en memoria de programa para guardar el estado en el ciclo anterior.

Bobina latch ENTRADA SALIDA 1001 1 ──]/\[─────────────────────────────────────────────────────────────────────(L)── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C024303E9 C60001 530000000000000000000000

La dirección especificada cambia a 1 si la lógica precedente es 1, y no se ve modificada si la lógica precedente es 0.

Puede ser forzado. Forzar una salida equivale a cumplir la lógica precedente. Por ello, forzar a OFF no hace que la salida sea 0, si no que se mantenga el estado anterior. Para poner a 0 la dirección es necesario forzar a ON la bobina unlatch asociada (ver siguiente apartado).

Page 52: DCSLLL

4 Interpretación MS-DOS Loader

51

Al comenzar la ejecución, durante el scan retentivo recuperan el último estado anterior al corte de alimentación.

Al estar dentro del bloque de salto de una instrucción NSKR o NSKD, mantienen el valor.

Codificación

Se codifica con tres Bytes:

1 Byte Opcode (hC6).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (hF6).

Forzado a OFF Opcode (hD6).

El funcionamiento descrito implica que el bit 21 almacene el valor de la dirección de trabajo y no el de la lógica precedente. Si se guardase el valor de la lógica precedente, suponiendo que varios ciclos anteriores se hubiese cumplido momentáneamente y la dirección hubiese sido escrita a uno, el bit histórico en el ciclo actual sería 0, por lo que al restaurar el sistema, se restauraría un 0 en la dirección y no un 1 como debería de ser.

Bobina unlatch ENTRADA SALIDA 1001 1 ──]\/[─────────────────────────────────────────────────────────────────────(U)── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C024B03E9 C70001 530000000000000000000000

La dirección especificada cambia a 0 si la lógica precedente es 1, y se mantiene a 0 si la lógica precedente es 0.

Puede ser forzado. Forzar una salida equivale a cumplir la lógica precedente. Por ello, forzar a ON no hace que la salida sea 1 si no 0. Para poner a 1 la dirección es necesario forzar a ON la bobina latch asociada (ver apartado anterior).

Al comenzar la ejecución, durante el scan retentivo recuperan el último estado anterior al corte de alimentación.

Al estar dentro del bloque de salto de una instrucción NSKR o NSKD, mantienen el valor.

Codificación

Se codifica con tres Bytes:

1 Byte Opcode (hC7).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (hF7).

Forzado a OFF Opcode (hD7).

El funcionamiento descrito implica que el bit 21 almacene el valor de la dirección de trabajo y no el de la lógica precedente. Si se guardase el valor de la lógica precedente,

Page 53: DCSLLL

4 Interpretación MS-DOS Loader

52

suponiendo que varios ciclos anteriores se hubiese cumplido momentáneamente y la dirección hubiese sido escrita a uno, el bit histórico en el ciclo actual sería cero, por lo que al restaurar el sistema, se restauraría un cero en la dirección y no un uno como debería de ser.

4.2.3.5. Instrucciones de bit simple Permiten acceder a bits de la zona de memoria de registros compuesta por registros de

16 bits (16+1 según el modelo de LM). Las direcciones varían entre 4096 y 8191, con posiciones de bit de 0 (bit menos significativo) hasta 15 (bit más significativo) para cada una de ellas. En el caso de trabajar con modelos de LM que usan registros 16+1, el bit de signo no puede ser accedido de esta forma, si no utilizando las instrucciones de contactos y bobinas ya descritas.

Leer bit ENTRADA SALIDA 4096 4097 ──]BR[────────────────────────────────────────────────────────────────────(BW)── 5 1 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 03A001 852003530000000000000000000000

Si el bit del registro de 16 bits especificado tiene un 1 y la lógica precedente es 1, permite seguir la secuencia en las instrucciones siguientes.

Puede ser forzado.

Codificación

En principio se tiene que codificar un rango de 4096 a 8191 para seleccionar la dirección de la palabra, y un rango de 0 a 15 para seleccionar el bit de la dirección.

De los ejemplos siguientes, se deduce que el rango máximo de 4096-8191 direcciones de palabras (16 bits = 2 Bytes) es descompuesto en Bytes, por lo que en verdad se tiene un rango de 0 a 8191 direcciones de bytes.

El Byte mas significativo de la primera palabra equivale a la dirección 0 y el menos significativo a la dirección 1, y así sucesivamente.

Así que el problema inicial se convierte en codificar un rango de 0 a 8191 para seleccionar la dirección del Byte, y un rango de 0 a 7 para seleccionar el bit del Byte.

Los siguientes ejemplos sirven para determinar la forma de codificar los rangos: 4096 4097 ──]BR[────────────────────────────────────────────────────────────────────(BW)── 0 0 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 030001 850003 530000000000000000000000 ENTRADA SALIDA 4096 4097 ──]BR[────────────────────────────────────────────────────────────────────(BW)── 5 1 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 03A001 852003 530000000000000000000000 ENTRADA SALIDA 4096 4097 ──]BR[────────────────────────────────────────────────────────────────────(BW)── 10 2

Page 54: DCSLLL

4 Interpretación MS-DOS Loader

53

0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 034000 854003 530000000000000000000000 4097 4098 ──]BR[────────────────────────────────────────────────────────────────────(BW)── 10 2 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 034002 854005 530000000000000000000000 8191 8191 ──]BR[────────────────────────────────────────────────────────────────────(BW)── 15 0 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 03FFFE 851FFF 530000000000000000000000

Se concluye que de los dos Bytes destinados a codificar la dirección del bit, se cogen los 3 bits más significativos para el rango de 0 a 7 y los 13 bits restantes para el rango de 0 a 8191.

Se codifica con tres Bytes:

1 Byte Opcode (h03).

2 Bytes Número de la dirección codificada en hexadecimal (Especial).

Al ser forzado:

Forzado a ON Opcode (h33).

Forzado a OFF Opcode (h13).

Ejemplo: 6143 6144 ──]BR[────────────────────────────────────────────────────────────────────(BW)── 15 15 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 03EFFE 85F000 530000000000000000000000

Cambiando la dirección de la palabra 6143 a un rango de 0 a 8191 Bytes, resulta que (6143-4096)*2 = 4094. Además como el bit 15 de la palabra 6143 corresponde al bit 7 del Byte de mayor, al hablar del MSB se mantiene el 4094 (si fuera el LSB seria 4095). Finalmente: 111 + 0 1111 1111 1110 = hEFFE como se quería comprobar.

Escribir bit ENTRADA SALIDA 4096 4097 ──]BR[────────────────────────────────────────────────────────────────────(BW)── 5 1 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 03A001 852003 530000000000000000000000

El bit especificado cambia a 1 si la lógica precedente es 1, o a 0 si la lógica precedente es 0.

Puede ser forzado.

Al estar dentro del bloque de salto de una instrucción NSKR o NSKD, mantienen el valor.

Page 55: DCSLLL

4 Interpretación MS-DOS Loader

54

Codificación

Se codifica con tres Bytes:

1 Byte Opcode (h85).

2 Bytes Número de la dirección codificada en hexadecimal (Especial), consultar apartado anterior.

Al ser forzado:

Forzado a ON Opcode (hB5).

Forzado a OFF Opcode (h95).

4.2.3.6. Instrucciones de temporizadores y contadores Los temporizadores y contadores se componen principalmente de un acumulador y un

preset. Ambos elementos equivalen a una dirección de la zona de registros, estando siempre el preset en la dirección anterior a la del acumulador.

En el caso de temporizadores, el valor del acumulador es incrementado desde cero con una frecuencia seleccionable entre tres bases de tiempo de 0,01, 0,1 y 1 segundo, hasta que iguala el valor del preset, momento en el que se produce una transición en la dirección de salida de acuerdo al tipo de temporizador seleccionado.

En el caso de contadores, el valor del acumulador es incrementado o decrementado de acuerdo a los flancos de dos entradas, hasta que iguala el valor del preset, momento en el que se produce una transición en la dirección de salida.

Por usar direcciones de la memoria de registros, el rango de contaje es de -32768 a +32767 para registros de 16 bits, o de -65535 a +65535 para registros de 16+1 bits.

Temporizador con retardo a ON – Base 1 segundo 1001 2001 ───] [────────────────────────────────────────────────────────────────────(TON)─ 5000 PRS 6001 5001 ACC 0 05000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 C803E9 4A1389 C407D1 5201 8813 00 1771 5300

Los temporizadores trabajan conjuntamente con salidas no retentivas (código hC4), que se modifican en el caso de un temporizador con retardo a ON de acuerdo al siguiente cronograma:

Figura 31. Cronograma temporizador con retardo a ON

Puede ser forzado.

<PRS =PRS

TIN ACC

OUT

Page 56: DCSLLL

4 Interpretación MS-DOS Loader

55

Cuando se realiza el scan retentivo, el acumulador se resetea a cero.

Queda claro que una vez el acumulador alcanza el valor del preset, éste deja de incrementarse y la salida cambia de estado. Sin embargo ¿Qué ocurre si posteriormente se modifica el valor del registro acumulador o preset de forma externa?

• En el caso de que el acumulador sea modificado con un valor inferior al del preset, vuelve a activarse la temporización.

• ? En el caso de que el acumulador sea modificado con un valor superior al del preset, no se ha podido determinar el comportamiento exacto por falta de un LM para realizar pruebas. Se ha supuesto que el temporizador se comporta igual que si el acumulador fuese igual al preset.

Codificación

Sabiendo que la dirección 5001 equivale al código h1389 y la dirección 2001 equivale al código h07D1, se deduce que el primer grupo de tres bytes codifica la dirección del acumulador, y el segundo la dirección de salida (opcode hC4 que corresponde a una instrucción de salida no retentiva).

Si se observa el código del programa, existe posteriormente un grupo de bytes comenzando con el código h52.

Después de varias pruebas se ha concluido que este grupo se encuentra al final de cada bloque de programa 4C, indicando el número de temporizadores y contadores que hay en el mismo y contiene los parámetros de configuración de cada temporizador y contador no incluidos en los dos primeros elementos de 3 bytes, como son la dirección del preset (5000 = h1388) y el valor de preset (6001 = h1771)

Así, esta instrucción se codifica con 8 Bytes + 5xN (número de temporizadores en la línea):

1er elemento: Código del temporizador

1Byte Opcode (h4A).

2 Bytes Dirección del acumulador codificada en hexadecimal (MSBLSB)

2º elemento: Código de salida no retentiva

1Byte Opcode (hC4).

2 Bytes Dirección codificada en hexadecimal (MSBLSB)

Al final de cada bloque de máximo 82 elementos:

1 Byte Opcode (h52).

1 Byte Número de temporizadores/contadores en el bloque codificado en hexadecimal. A su vez indica el número de veces que se repite el siguiente bloque, pues hay uno por cada uno de los temporizadores/contadores.

2 Bytes Dirección del preset codificada en hexadecimal (LSB MSB).

1 Byte Código h00

2 Bytes Valor de preset codificado en hexadecimal (MSB LSB)

Si el usuario fuerza el temporizador, el LM se limita a forzar el elemento de opcode hC4 (salida no retentiva) asociado.

Page 57: DCSLLL

4 Interpretación MS-DOS Loader

56

Al tener el código h4A y, tal y como se comprobará una vez evaluadas todas las instrucciones, no ser utilizados los opcodes h5A, h6A y h7A en otros elementos, se ha pensado que el sistema puede utilizar los bits históricos para almacenar información.

Para comprobarlo, se modificó el opcode h4A en el código del archivo *.ldr mediante un editor hexadecimal y luego se cargó en el MS-DOS loader. Se obtuvo error de opcode con los códigos h5A y h7A, pero no con el h6A, para el que el MS-DOS Loader se comportaba como si fuese el código h4A. Que se permita poner el bit histórico 21 (bit con el valor del estado anterior) a uno apoya la hipótesis.

Temporizadores en la memoria de programa Al añadir al programa un temporizador retentivo, el número de registros libres de la

memoria de programa se reduce en dos.

Si a esto se añade que una búsqueda1 en el LM de la dirección del preset no produce ningún resultado pero sí que se encuentra la dirección del acumulador (hay que tener en cuenta que no es necesario especificar la dirección del preset pues es la del acumulador menos uno), se deduce que el bloque final que comienza con el código h52 no se carga en memoria de programa.

Esto implica que tampoco se guarda el valor del preset, por lo que cuando se produce la transferencia del programa entre el PC (MS-DOS Loader) y el LM se debe de escribir en memoria de registros el valor deseado en la dirección del preset. Así se explica por que en la realidad una vez se ha modificado el valor ya sea por programa o por edición del usuario, no se restaure el valor original a no ser que se realice una nueva transferencia desde el PC.

Queda averiguar como se actualiza el registro del acumulador con la frecuencia seleccionada.

Actualización del acumulador para los de base de tiempo 0,01 segundos

En la información disponible se encuentra el siguiente párrafo “los temporizadores de base 0,01 segundos son actualizados por el procesador con una base de interrupción de 0,01 segundo. Por este motivo, el error máximo en cualquier temporizador con resolución 0,01 es un scan de programa. Este tiempo puede reducirse programando múltiples temporizadores con la mismas direcciones de bobina, acumulador y preset.”

Actualizar los acumuladores mediante interrupciones se puede hacer al menos de dos formas:

• Cada vez que se recibe la interrupción se realiza una lectura del programa en memoria, se localizan los temporizadores de 0,01 segundos y si la lógica precedente está en el estado adecuado, se actualizan.

• Al comienzo de la ejecución se memorizan las posiciones de los temporizadores y cada vez que se recibe la interrupción se accede a ellas y se actualizan si es necesario.

1 Una vez el programa esta cargado en memoria, el MS-DOS Loader permite realizar

búsquedas de distintos elementos en el programa, entre ellos, direcciones de la tabla de E/S.

Page 58: DCSLLL

4 Interpretación MS-DOS Loader

57

La primera opción conlleva una gran pérdida de tiempo al tener que realizar una lectura del programa en memoria por cada interrupción, por lo que se va a implementar la segunda opción.

En ambos casos es necesario indicar al procesador qué timers necesitan ser actualizados y cuales no, pues no debe de evaluarse la lógica precedente en el momento de la interrupción, si no en el momento en que se ejcuta la línea según el scan normal. Tal vez el LM utilice el bit 21 para guardar dicha información, al menos esta es la forma en que se va a implementar.

Conviene destacar que, aunque por la interrupción se actualice el acumulador y el valor de éste iguale al del preset, la salida asociada no se actualizará hasta que se evalúe la línea de lógica, de ahí el comentario de distribuir la misma línea en distintos puntos del programa, para reducir el error de temporización.

Actualización del acumulador para los de base de tiempo 0,1 y 1 segundos

Ni en el párrafo leído ni en ningún otro relacionado con interrupciones se mencionan los temporizadores de 0,1 y 1 segundos, lo que hace pensar que no se actualizan a base de interrupciones.

De las pruebas realizadas con el LM se ha observado que los temporizadores de 0,1 segundos, al trabajar con un ciclo superior a este tiempo, no temporizan correctamente el tiempo establecido sino uno mayor. Se apreció que si, por ejemplo, se estaba trabajando con un ciclo de 0,15 segundos, un temporizador de 10 segundos temporizaba 15 segundos. (En el caso de haber utilizado un temporizador de base 0,01, el tiempo temporizado máximo hubiese sido de 10,15 segundos). Sin embargo, al cambiar a temporizadores de base 1 segundo, el tremendo error desaparecía.

Existen dos formas de implementar una temporización con estas características:

• Actualizar los temporizadores al comienzo o final del ciclo si han transcurrido 0,1 ó 1 segundos desde la última vez que se actualizaron: Se podría utilizar el mismo método de actualización que en el caso de interrupciones: utilizar el bit 21 para indicar qué temporizador necesita ser actualizado y un listado con la posición de todos los temporizadores de cada base.

• Actualizar los temporizadores a medida que son evaluados: Al comienzo del ciclo se determinaría si en ese ciclo se deben de actualizar los temporizadores de 0,1 y 1 segundos. De esta forma se evita tener que realizar ciclos de actualización.

La primera opción no debe de ser la utilizada por el LM, pues entonces se podrían haber usado interrupciones reduciendo el error de temporización ya que se necesitan los mismos recursos.

? El problema de la segunda opción es que al no llevarse un control de los acumuladores actualizados, un mismo acumulador se incrementaría en un ciclo tantas veces como en líneas apareciese. Esto último sería fácil de comprobar en el LM, sin embargo, ha sido imposible por falta de disponibilidad de LM para realizar la prueba. Se ha supuesto que ésta es la forma de trabajar, pues ahorra en memoria y en tiempo.

Además existe otra característica que apoya esta forma de funcionamiento. Tal y como se verá en el apartado 4.2.3.8 Instrucciones de referencia de memoria, cuando se produce una salto de líneas de lógica, los temporizadores en ellas incluidos dejan de ser actualizados.

Page 59: DCSLLL

4 Interpretación MS-DOS Loader

58

Temporizador con retardo a ON – Base 0.1 segundos 1001 2001 ───] [────────────────────────────────────────────────────────────────────(TON)─ 5000 PRS 6001.0 5001 ACC 0.0 05000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 C803E9 491389 C407D1 5201 8813 00 EA6A 5300

La única diferencia con el anterior, es que en éste con base 0,1 segundo el acumulador se incrementa 10 veces más rápido y cambia el opcode del primer elemento a h49.

Temporizador con retardo a ON – Base 0.01 segundos 1001 2001 ───] [────────────────────────────────────────────────────────────────────(TON)─ 6000 PRS 601.00 6001 ACC .00 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 C803E9 681771 C407D1 5201 7017 00 EAC4 5300

La única diferencia con el de base 1 segundo, es que en este con base 0,01 segundo el acumulador se incrementa 100 veces más rápido y cambia el opcode del primer elemento a h68.

Los modelos de procesador 620-25/35 solo aceptan los temporizadores de base 0,01 segundos en las direcciones de registros 4097-4111. Como cada temporizador ocupa dos direcciones, estos dos modelos de procesador permiten un máximo de 8 temporizadores de base 0,01 segundos.

Temporizador con retardo a OFF – Base 1 segundo 1001 2001 ───] [────────────────────────────────────────────────────────────────────(TOF)─ 5000 PRS 6010 5001 ACC 0 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 C803E9 421389 C407D1 5201 8813 00 177A 5300

La salida no retentiva (código hC4) asociada, se modifica en el caso de un temporizador con retardo a OFF de acuerdo al siguiente cronograma:

Page 60: DCSLLL

4 Interpretación MS-DOS Loader

59

Figura 32. Cronograma temporizador con retardo a OFF

Todo lo explicado en el temporizador con retardo a ON con base 1 segundo, es aplicable a esta instrucción con las siguientes diferencias:

• Cuando se realiza el scan retentivo el acumulador toma el valor del preset.

• El opcode del primer elemento es h42. (De igual forma, el único bit histórico que permite modificar el MS-DOS Loader es el bit 21, código h62).

Temporizador con retardo a OFF – Base 0.1 segundos 1001 2001 ───] [────────────────────────────────────────────────────────────────────(TOF)─ 5000 PRS 6010.0 5001 ACC 0.0 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 C803E9 411389 C407D1 5201 8813 00 EAC4 5300

La única diferencia con el anterior es que en éste con base de 0,1 segundos, el acumulador se incrementa 10 veces más rápido y cambia el opcode del primer elemento a h41.

Temporizador con retardo a OFF – Base 0.01 segundos 1001 2001 ───] [────────────────────────────────────────────────────────────────────(TOF)─ 5000 PRS 601.00 5001 ACC .00 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 C803E9 601389 C407D1 5201 8813 00 EAC4 5300

La única diferencia con el de base de 1 segundo es que en este con base de 0,01 segundos, el acumulador se incrementa 100 veces más rápido y cambia el opcode del primer elemento a h60.

Los modelos de procesador 620-25/35 solo aceptan los temporizadores de base 0,01 segundos en las direcciones de registros 4097-4111. Como cada temporizador ocupa dos direcciones, estos dos modelos de procesador permiten un máximo de 8 temporizadores de base 0,01 segundos.

<PRS =PRS

TIN

ACC

OUT

Page 61: DCSLLL

4 Interpretación MS-DOS Loader

60

Temporizador retentivo – Base 1 segundo ┌──────────────┐ 1001 │ │ 2001 ───] [──┤ TRN OUT ├───────────────────────────────────────────────────( )── │ │ │ 7000 │ │ PRS │ │ 8001 │ │ │ │ 7001 │ 1003 │ ACC │ ───] [──┤ RST 0 │ └──────────────┘ 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 C803E9 C903EB 4E1B59 C407D1 5201 581B 00 1F41 530000000000000000000000000000

En el caso de un temporizador retentivo la salida se modifica de acuerdo al siguiente cronograma:

Figura 33. Cronograma temporizador retentivo

Sin embargo, al no ser elemento de final de línea como le pasaba a los temporizadores con retardo, pueden trabajar con lógica posterior a su posición, por lo que pueden trabajar con cualquier tipo de salida, no solo no retentivas (hC4).

No permite paralelos en las líneas lógicas de entrada.

Cuando se realiza el scan retentivo el acumulador se resetea a cero.

Codificación

Todo lo explicado en el temporizador con retardo a ON con base 1 segundo, es aplicable a esta instrucción con pequeñas diferencias:

• Como se puede observar, en el código aparece un elemento con opcode hC9 a pesar de que no existe ninguna rama paralelo en la lógica precedente (ver apartado 4.2.3.18 Interconexión de elementos). Se deduce que como se trabaja con dos líneas de entradas (TIN y RST) y es necesario indicar el cambio de línea, los códigos de ramificación se interpretan como comienzo de la segunda línea. Es por esto que no se permite lógica en paralelo antes de un temporizador retentivo.

• El opcode del primer elemento es h4E. (De igual forma, el único bit histórico que permite modificar el MS-DOS Loader es el bit 21, código h6E).

<PRS =PRS

TIN

ACC

OUT

RST

Page 62: DCSLLL

4 Interpretación MS-DOS Loader

61

Temporizador retentivo – Base 0.1 segundo ┌──────────────┐ 1001 │ │ 2001 ───] [──┤ TRN OUT ├───────────────────────────────────────────────────( )── │ │ │ 7000 │ │ PRS │ │ 6001.0│ │ │ │ 7001 │ 1003 │ ACC │ ───] [──┤ RST 0.0│ └──────────────┘ 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 C803E9 C903EB 4D1B59 C407D1 5201 581B 00 EA6A 530000000000000000000000000000

La única diferencia con el anterior, es que en éste con base 0,1 segundo el acumulador se incrementa 10 veces más rápido y cambia el opcode del primer elemento a h4D.

Temporizador retentivo – Base 0.01 segundo ┌──────────────┐ 1001 │ │ 2001 ───] [──┤ TRN OUT ├───────────────────────────────────────────────────( )── │ │ │ 7000 │ │ PRS │ │ 601.00│ │ │ │ 7001 │ 1003 │ ACC │ ───] [──┤ RST .00│ └──────────────┘ 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 C803E9 C903EB 6C1B59 C407D1 5201 581B 00 EAC4 530000000000000000000000000000

La única diferencia con el de base 1 segundo, es que en este con base 0,01 segundo el acumulador se incrementa 100 veces más rápido y cambia el opcode del primer elemento a h6C.

Los modelos de procesador 620-25/35 sólo aceptan los temporizadores de base 0,01 segundos en las direcciones de registros 4097-4111. Como cada temporizador ocupa dos direcciones, estos dos modelos de procesador permiten un máximo de 8 temporizadores de base 0,01 segundos.

Contador ┌──────────────┐ 1001 │ │ 2001 ───] [──┤ CTU OUT ├───────────────────────────────────────────────────( )─ │ │ │ 5000 │ 1002 │ PRS │ ───] [──│ CTD 6001 │ │ │ │ 5001 │ 1003 │ ACC │ ───] [──┤ RST 0 │ └──────────────┘ 0A000080001000080500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C05 C803E9 C903EA C903EB 4F1389 C407D1 5201 8813 00 1771 530000000000000000000000

Page 63: DCSLLL

4 Interpretación MS-DOS Loader

62

En el caso de un contador la salida se modifica de acuerdo al siguiente cronograma:

Figura 34. Cronograma temporizador retentivo

Sin embargo, al no ser elemento de final de línea como le pasaba a los temporizadores con retardo, pueden trabajar con lógica posterior a su posición, por lo que pueden trabajar con cualquier tipo de salida, no solo no retentivas (hC4).

No permite paralelos en las líneas lógicas de entrada.

Cuando se realiza el scan retentivo el acumulador se resetea a cero.

Queda claro que una vez el acumulador alcanza el valor del preset, éste deja de incrementarse, aunque se reciban nuevos flancos en la entrada CTU, y la salida cambia de estado. Sin embargo ¿Qué ocurre si posteriormente se modifica el valor del registro acumulador o preset de forma externa?

• En el caso de que el acumulador sea modificado con un valor inferior al del preset, vuelve a activarse el contaje.

• En el caso de que el acumulador sea modificado con un valor superior al del preset, extrañamente, vuelve a activarse el contaje.

• La salida sólo es uno, cuando el acumulador es igual al preset.

• Cuando se alcanzan los limites -65535 o 65535 permitidos por el registro acumulador (16+1 bits), el valor deja de decrementarse o incrementarse.

Codificación

Todo lo explicado en el temporizador con retardo a ON con base 1 segundo, es aplicable a esta instrucción con pequeñas diferencias:

• Como se puede observar, en el código aparece un elemento con opcode hC9 a pesar de que no existe ninguna ramificación en la lógica precedente (ver apartado 4.2.3.18 Interconexión de elementos). Se deduce que como se trabaja con tres líneas de entradas (CTU, CTD y RST) y es necesario indicar el cambio de línea, los códigos de ramificación se interpretan como comienzo de la siguiente línea. Es por esto que no se permite lógica en paralelo antes de un contador.

• El opcode del primer elemento es h4F. En el caso de un contador el MS-DOS Loader reconoce el elemento modificando cualquiera de los bits históricos, así se pueden obtener los códigos h5F, h6F y h7F.

Detección de flancos

Para poder incrementar y decrementar el acumulador, es necesario que el LM detecte los flancos ascendentes en las entradas CTU y CTD respectivamente, para lo que es

<PRS =PRS

CTU

ACC

OUT

CTD RST

Page 64: DCSLLL

4 Interpretación MS-DOS Loader

63

necesario disponer de dos bits que guarden el estado de las dos entradas en el ciclo anterior.

Si se tiene en cuenta lo expuesto en el apartado anterior (el LM acepta la modificación de los dos bits históricos interpretando siempre un contador no forzado), se deduce que es en los bits históricos donde guarda la información.

Ya que no se puede saber qué bit guarda qué entrada se supone que:

Bit histórico 20 (forzado) Estado ciclo anterior entrada CTD

Bit histórico 21 (histórico) Estado ciclo anterior entrada CTU

Combinación de Instrucciones Contador y temporizador

┌──────────────┐ 1001 │ │ 4001 ───] [──┤ CTU OUT ├──────────────────────────────────────────────────(TOF)─ │ │ │ 7000 │ │ PRS │ ────────│ CTD 8001 │ 6000 │ │ PRS │ 7001 │ 5001 │ ACC │ ────────┤ RST 0 │ 6001 └──────────────┘ ACC 0 0A000080001000080600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C06 C803E9 C17FFF C17FFF 4F1B59 421771 C40FA1 5202 581B 00 1F41 7017 00 1389 53000000

Lógica antes de un temporizador retentivo o contador ┌──────────────┐ 1001 1002 1003 │ │ 4001 ───] [─────] [─────] [──┤ CTU OUT ├───────────────────────────────────( )── │ │ │ 7000 │ 2001 2002 │ PRS │ ───] [─────] [──────────│ CTD 8001 │ │ │ │ 7001 │ 3001 │ ACC │ ───] [──────────────────┤ RST 0 │ └──────────────┘ 0A000080001000080800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C08 C803E9 C803EA C803EB C907D1 C807D2 C90BB9 4F1B59 C40FA1 5201 581B 00 1F41 530000

Solo admite elementos en serie en cualquiera de las tres líneas de entrada.

C8 #### + C8… Primera línea.

C9 #### + C8… Segunda y tercera líneas.

Lógica después de un contador

Admite lógica compleja.

Page 65: DCSLLL

4 Interpretación MS-DOS Loader

64

┌──────────────┐ 1001 │ │ 1002 1003 1004 4001 ───] [──┤ CTU OUT ├───] [──┬──] [─────] [──┬──────────────────────────( )── │ │ │ │ │ 7000 │ │ │ │ PRS │ │ 2001 2002 │ ────────│ CTD 8001 │ ├──] [──┬──] [──┼ │ │ │ │ │ 7001 │ │ │ │ ACC │ │ 3001 │ ────────┤ RST 0 │ ├──] [──┴ └──────────────┘ 0A000080001000080D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C0D C803E9 C17FFF C17FFF 4F1B59 C803EA C903EB C803EC C907D1 C907D2 C90BB9 C37FFF C37FFF C40FA1 5201 581B 00 1F41 53000000

La codificación para la lógica posterior es la misma que si no hubiera un temporizador retentivo o contador en la línea.

4.2.3.7. Instrucciones de salto Las instrucciones de salto son utilizadas en procesos donde existen subprocesos (partes

de programa) que interesan ser ejecutados o no (saltados) dependiendo de condicionantes lógicos internos o externos.

Estas instrucciones sirven para delimitar el bloque de líneas que define el subproceso. Las instrucciones NSKR o NSKD marcan el principio, y la instrucción EOS el final.

No salto con retención 1001 ───] [────────────────────────────────────────────────────────────────────NSKR── 5001 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 C803E9 461389 530000000000000000000000

Rango de saltos entre 0 - 8191 y 8449 – 32767.

Si la lógica precedente es 0, se salta por encima de las líneas de lógica hasta alcanzar la instrucción de final de salto. Al mismo tiempo se retiene el estado ON/OFF en las salidas booleanas y se congelan los datos en las salidas enteras. Los temporizadores programados en las líneas saltadas dejan de actualizarse. Si no existe instrucción de fin de salto o ésta, erróneamente, se encuentra antes de la instrucción NSKR, el salto se desactiva al acanzar el final del programa.

Puede ser forzado.

Un detalle importante es que no se salta directamente a la línea de final de salto, si no que la instrucción de final de salto se alcanza leyendo las líneas intermedias. Esto se comprueba fácilmente, pues el tiempo de scan no se ve afectado esté o no esté activado el salto.

Codificación

1 Byte Opcode (h46).

2 Bytes Número de salto (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (h76).

Forzado a OFF Opcode (h56).

Page 66: DCSLLL

4 Interpretación MS-DOS Loader

65

Como se siguen leyendo aunque no se evalúen las líneas intermedias, el LM no necesita guardar la dirección de destino del salto.

No salto con desactivación 1001 ───] [────────────────────────────────────────────────────────────────────NSKD── 5001 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 C803E9 471389 530000000000000000000000

Rango de saltos entre 0 - 8191 y 8449 – 32767.

Si la lógica precedente es 0, se salta por encima de las líneas de lógica hasta alcanzar la instrucción de final de salto. Si no existe instrucción de fin de salto o ésta, erróneamente, se encuentra antes de la instrucción NSKR, el salto se desactiva al acanzar el final del programa.

En el primer ciclo en el que se activa el salto, se borra el estado en las salidas booleanas y los datos en algunas salidas enteras (comportamiento NSKD), mientras que en los sucesivos se retiene el estado ON/OFF en las salidas booleanas y se congelan los datos en las salidas enteras (comportamiento NSKR). Para que vuelva a comportarse como un NSKD, el salto debe desactivarse y activarse.

Por ello, si después del primer ciclo (comportamiento NSKD), se modifica el valor de las salidas que en el primer ciclo fueron reseteadas ya sea manualmente o en líneas de lógica externas al bloque de salto, estos nuevos valores se mantienen en los sucesivos ciclos (comportamiento NSKR).

Completando los datos del manual del programador con las pruebas realizadas con el LM, las instrucciones de salida cuyos datos son borrados por un NSKD son las siguientes.

Instrucción Símbolo Salida no retentiva ( ) Salida retentiva (R) Temporizador de retardo (Dirección de salida) TON,TOFF Temporizador de retardo (Dirección de acumulador) TON,TOFF Escritura de datos (S2) Escritura de datos indirecta (Dirección destino)1 <I2> Escritura de datos 1-8 bloques de 16 bits zona I/O (PSH) Escritura de datos 1-8 bloques de 16 bits zona registros (PSH)

Tabla 11. Instrucciones afectadas por un NSKD.

Puede ser forzado.

Codificación

1 Byte Opcode (h47).

2 Bytes Número de salto codificado en hexadecimal (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (h77).

1 El valor de la dirección intermedia no se ve afectado.

Page 67: DCSLLL

4 Interpretación MS-DOS Loader

66

Forzado a OFF Opcode (h57).

El resto de características coincide con la instrucción anterior “No salto con retención”.

La característica que un salto NSKD se comporte en el primer ciclo de una forma y de otra en los siguientes, exige que en algún sitio se almacene si el actual es el primer ciclo con el salto activo o no. Considerando que el primer ciclo de un NSKD se produce cuando el bit histórico 21 (histórico) contiene un 1, es fácil deducir que es este bit el que se usa para guardar dicha información.

Así:

Bit histórico 21 (histórico) a 1 Primer ciclo Comportamiento NSKD.

Bit histórico 21 (histórico) a 0 No primer ciclo Comportamiento NSKR.

Para comprobarlo se ha modificado el programa *.ldr con un editor, modificando el opcode h47 por el h67 (bit 21 a 1) para el que el MS-DOS Loader no presentaba ningún error. Se ha realizado lo mismo con el opcode h46 (salto NSKR), cambio con el que el MS-DOS Loader si que presentaba un error de opcode no válido, ya que en este caso el procesador no necesita guardar ninguna información adicional.

? Trabajar de esta forma implica que al forzar el elemento a OFF (bit historico 20 a 1 y bit histórico 21 a 0) no se produciría en ningún momento el comportamiento NSKD. Como no se han podido realizar pruebas que lo confirmen o lo desmientan, es la forma en que se ha implementado.

Final de salto ───────────────────────────────────────────────────────────────────────────EOS── 5001 0A000080001000080100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C01 341389 530000000000000000000000000000

Rango de saltos entre 0 - 8191 y 8449 – 32767.

Utilizado con las instrucciones NSKR y NSKD marca el final de salto de un bloque de líneas.

De las pruebas se ha determinado que aunque al programar la línea acepta lógica anterior, da igual que el resultado sea 0 ó 1 pues siempre se considera que el final de salto está activo. También se ha comprobado que puede programarse más de un EOS con igual número, pero siempre considera final de salto el primero.

Éste funcionamiento coincide con lo expuesto en la instrucción de salto NSKR que decía que se seguían leyendo pero no evaluando las líneas lógicas hasta encontrar la instrucción de final de salto.

Codificación

1 Byte Opcode (h34).

2 Bytes Número de salto codificado en hexadecimal (MSB LSB).

4.2.3.8. Instrucciones de referencia de memoria

Estas instrucciones son utilizadas para redireccionar la normal secuencia del flujo en la ejecución de un programa.

Se clasifican en dos grupos:

Page 68: DCSLLL

4 Interpretación MS-DOS Loader

67

• Instrucciones jump: Son variantes de la instrucción de salto NSKR. Se diferencian en que la ejecución del programa salta directamente a la posición de memoria ocupada por la instrucción de final de salto correspondiente.

• Instrucciones de subrutina: Permiten saltar directamente a la posición de memoria donde comienza un bloque de programa lógico. Una vez éste se ha ejecutado, permiten retornar a la posición siguiente a la que produjo el redireccionamiento.

Salto 1001 ───] [────────────────────────────────────────────────────────────────────NSKR── 8192 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 C803E9 462000 530000000000000000000000 1001 ───] [────────────────────────────────────────────────────────────────────NSKR── 8447 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 C803E9 4620FF 530000000000000000000000

Rango de saltos entre 8192 - 8447. Así se diferencia de la instrucción de salto NSKR que admite los rangos 0 – 8191 y 8449 – 32767, pues el símbolo es el mismo.

Si la lógica precedente es 0, salta a la posición de memoria de programa de final de salto. Al mismo tiempo retiene el estado ON/OFF en las salidas booleanas y congela los datos en las salidas enteras. Los temporizadores programados en las líneas saltadas dejan de actualizarse. Si no existe instrucción de fin de salto o ésta, erróneamente, se encuentra antes de la instrucción NSKR, el salto se desactiva al acanzar el final del programa.

Puede ser forzado.

Codificación

1 Byte Opcode (h46).

2 Bytes Número de salto (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (h76).

Forzado a OFF Opcode (h56).

Saltar directamente a la posición de destino implica que no se leen las líneas intermedias buscando el siguiente final de salto como ocurría anteriormente. Aparece por tanto la necesidad de almacenar la posición de memoria a la que tiene que saltar cada uno de los NSKR existentes en programa, en caso de ser activados.

Como esta posición no se almacena en la memoria de programa ya que se ha comprobado que cada elemento de salto ocupa solo los tres bytes que codifican el opcode y el número de salto, el procesador debe de tener una zona dedicada donde almacenar la información de cada uno de ellos.

Teniendo en cuenta que el rango de saltos es 8192-8447, se necesita almacenar 256 elementos.

? Saltar directamente a la posición de destino presenta un problema con los temporizadores de base 0,01 segundos al ser actualizados por interrupciones. Si no se evalúan las líneas en las que aparecen estos temporizadores por haber sido saltadas, no se

Page 69: DCSLLL

4 Interpretación MS-DOS Loader

68

pueden desactivar los bits que indican a la interrupción qué temporizadores actualizar, por lo que sus acumuladores siguen actualizándose a pesar de estar dentro de un NSKR activo. Por falta de LM con el que realizar las pruebas necesarias, no se ha podido determinar si éste es el comportamiento real.

Salto indirecto 1001 2001 ───] [────[B2]────────────────────────────────────────────────────────────NSKR── 0 8448 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 C803E9 8807D1 462100 530000000000000000

Número de salto 8448.

Utiliza el número de salto 8448 para diferenciarse con el resto de saltos NSKR (0-8447, 8449-32767).

Se diferencia de los anteriores en que utiliza como número de salto el valor guardado en la pila por la última dirección de escritura.

Así, si la lógica precedente es 0 y el valor recuperado corresponde al rango 8192-8447 se salta directamente a la posición del EOS correspondiente, o si por el contrario corresponde al rango 0-8191, 8449-32767 se leen pero no se evalúan las líneas intermedias hasta el primer EOS.

Puede ser forzado.

Codificación

1 Byte Opcode (h46).

2 Bytes Número de salto (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (h76).

Forzado a OFF Opcode (h56).

Final de salto 1001 ───] [─────────────────────────────────────────────────────────────────────EOS── 8447 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 C803E9 3420FF 530000000000000000000000

Rango de saltos 8192 - 8448.

Si la lógica precedente es 1, se considera final de salto activo. Sin embargo, las instrucciones de salto directo pueden trabajar con distintos finales de salto EOS, con las particularidades que se describen a continuación:

• En el caso de que no exista ningún EOS activo, el último EOS da igual que esté activo o no, es final de salto.

• Si hay dos finales de salto activos, el último es final de salto.

• Si hay dos finales de salto, para las siguientes secuencias de activación, una vez se ha activado el salto NSKR, el resultado es el siguiente:

- Primer EOS activo, último EOS no activo primer EOS fin de salto.

Page 70: DCSLLL

4 Interpretación MS-DOS Loader

69

- Se activa último EOS último EOS fin de salto.

- Se desactiva último EOS último EOS fin de salto. No se vuelve al primer EOS como final de salto, para que la línea vuelva a ser evaluada.

Codificación

1 Byte Opcode (h34).

2 Bytes Número de salto (MSB LSB).

Del funcionamiento descrito, se concluye que la evaluación de si un EOS está activado o no, se determina en el ciclo anterior. Conclusión apoyada por las siguientes afirmaciones:

• Al evaluar los EOS a medida que aparecen en la secuencia normal del scan se explica por qué la dirección de salto es la del último EOS.

• Mientras no aparece un EOS activo, el procesador actualiza la posición de destino con la del EOS que tiene en ese momento.

• Si aparece un EOS activo, el procesador guarda su posición y no la sobrescribe a no ser que aparezca otro activo.

• Al no volver a evaluar las líneas saltadas, un EOS saltado nunca podrá volver a ser final de salto mientras no se desactive el salto.

Salto a subrutina 1001 0 ───] [─────────────────────────────────────────────────────────────────────JSR── 255 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 C803E9 0480FF 040000 530000000000000000 1001 0 ───] [─────────────────────────────────────────────────────────────────────JSR── 0 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 C803E9 048000 040000 530000000000000000

Rango de subrutinas 0 - 255.

Si la lógica precedente es 1, salta a la posición de memoria de programa siguiente a la ocupada por la instrucción de comienzo de subrutina (SUB).

Codificación

1 Byte Opcode (h04).

1 Byte Código (h80).

1 Byte Número de salto.

1 Byte Opcode (h04).

2 Byte Posición de memoria de salto.

En la información disponible se encuentra el siguiente párrafo “Si una JSR tiene un número no válido (no existe instrucción SUB) el procesador volverá al comienzo de la memoria de programa si la lógica precedente es 1. La instrucción JSR es visualizada con un cero encima en este caso”.

Page 71: DCSLLL

4 Interpretación MS-DOS Loader

70

De esto se deduce que al igual que ocurre con el valor histórico, la posición en memoria de programa del elemento de comienzo de la subrutina se almacena en la memoria de programa.

En este caso es posible hacerlo ya que, a diferencia de la instrucción NSKR en la que la posición de destino varía en función del EOS activo (implicaría volver a la posición del elemento NSKR para escribir la dirección de destino para cada EOS evaluado), la posición de destino donde se encuentra la instrucción SUB es fija y determinada al realizar la carga del programa en memoria, pues se ha comprobado que el MS-DOS Loader no la inicializa en ningún momento. En el caso de existir erróneamente dos bloques de subrutina con el mismo número, por ser evaluados secuencialmente, la instrucción de salto siempre saltará a la última intrucción SUB.

Subrutina 1001 ───] [─────────────────────────────────────────────────────────────────────SUB── 255 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 C803E9 2480FF 530000000000000000000000

Sólo en el caso en que la línea sea evaluada por aparecer en el scan normal de programa (no como resultado de una instrucción JSR, recuérdese que la instrucción JSR salta a la posición siguiente a la ocupada por el elemento SUB), si la lógica precedente es 0, la instrucción JSR se comporta exactamente igual que la instrucción NSKR.

Codificación

1 Byte Opcode (h24).

1 Byte Código (h80).

1 Byte Número de salto.

Retorno de subrutina 1001 ───] [─────────────────────────────────────────────────────────────────────RTS── 255 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 C803E9 1480FF 530000000000000000000000

Si la lógica precedente es 1, el procesador vuelve a la línea de lógica inmediatamente posterior a la instrucción JSR que produjo el salto. Si es 0, el procesador ejecuta la línea de lógica siguiente a la instrucción RTS.

Codificación

1 Byte Opcode (h14).

1 Byte Código (h80).

1 Byte Número de salto.

A diferencia de la instrucción JSR, en la que el salto siempre se produce a una posición de memoria de programa fija, la posición de retorno al poderse trabajar con varios JSR varía en función de que JSR produjo el salto, por lo que esta debe de ser guardada un zona de memoria interna al procesador, tal y como se dedujo en el caso de los NSKR.

Teniendo en cuenta que el rango de subrutinas es 0-255, se necesitan 256 elementos.

Page 72: DCSLLL

4 Interpretación MS-DOS Loader

71

? Este funcionamiento que no utiliza la pila del sistema para almacenar las direcciones de retorno, impide que una subrutina se llame a sí misma, pues se perdería la dirección de retorno de la primera llamada al ser sobrescrita con la de la segunda llamada. Debido a la inestabilidad que podría producir la prueba necesaria en un LM real, si es éste el funcionamiento, se ha preferido suponer directamente que es así.

Retorno al inicio del programa 1001 ───] [─────────────────────────────────────────────────────────────────────RBP── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 C803E9 057FFF 530000000000000000000000

Si la lógica precedente es 1, el procesador vuelve a la primera posición de la memoria de programa, comenzándose un nuevo ciclo.

Puede ser forzado.

Codificación

1 Byte Opcode (h05).

2 Bytes Código (h7F FF).

Al ser forzado:

Forzado a ON Opcode (h35).

Forzado a OFF Opcode (h15).

4.2.3.9. Instrucciones de manipulación de datos Estas instrucciones son utilizadas para recoger, transferir y comparar datos almacenados

en las tablas de estados E/S, tabla de estados del sistema o tabla de registros.

Se clasifican en tres categorías:

• De manipulación de datos enteros con modo de direccionamiento directo1: Bring in indirecto, Send out indirecto. Son utilizadas para transferir palabras de datos de 16 bits entre las tablas y el buffer de trabajo en el procesador llamado pila (“stack”).

• De manipulación de datos enteros con modo de direccionamiento indirecto2: Bring in, Send out, constante, Pull, Push, Puls. Son utilizadas para transferir palabras de datos de 16 bits entre las tablas y el buffer de trabajo en el procesador llamado pila.

• De manipulación de datos en coma flotante: Bring in en coma flotante, Send out en coma flotante, Constante en coma flotante. Son utilizadas para transferir palabras de datos de 32 bits entre las tablas y el buffer de trabajo en el procesador llamado pila.

1 El modo de direccionamiento directo es aquel, en el que la dirección dada contiene el

valor con el que realizar las operaciones. 2 El modo de direccionamiento indirecto es aquel, en el que la dirección dada contiene

otra dirección que a su vez contiene el valor con el que realizar las operaciones.

Page 73: DCSLLL

4 Interpretación MS-DOS Loader

72

En toda la documentación consultada, la mayor descripción que se hace de la pila es la siguiente: “Área de almacenaje temporal utilizada por el procesador para mantener cualquier dato numérico que va a ser procesado; valores numéricos obtenidos por algunas instrucciones de manipulación de datos (Bring in, Pull, constante), así como resultados de operaciones matemáticas son escritos en el stack; otras instrucciones de manipulación de datos (Send Out, Push) leen valores numéricos desde el stack y los transfieren a la dirección especificada. El stack no puede ser accedido o visualizado directamente.”

Se han realizado pruebas para deducir el funcionamiento. Al final de este capítulo se resumen las conclusiones.

Bring in 15 4097 ──[B2]────────────────────────────────────────────────────────────────────(S2)── 0 0 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 88000F 071001 530000000000000000000000

Si la lógica precedente es 1, recoge un valor entero de la dirección indicada y lo deposita en la pila.

Rango de direcciones 15-8191.

Si la dirección es menor de 4096 coge 16 direcciones consecutivas de la zona I/O, por ello solo se pueden especificar direcciones de la 15 en adelante (al especificar la dirección 15 coge los bits de las posiciones 0-15), donde N (dirección especificada) ocupa el bit de mayor peso y la dirección N-15 el bit de menor peso de la palabra de 16 bits creada.

Si la dirección está en el rango 4096-8191 coge directamente el dato entero teniendo en cuenta el bit de signo.

Codificación

1 Byte Opcode (h88).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Bring in indirecto 5001 6001 ──<B2>────────────────────────────────────────────────────────────────────(S2)── 0 0 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 891389 071771 530000000000000000000000

Si la lógica precedente es 1, recoge un valor entero de la dirección indicada (dirección de referencia), siendo este dato a su vez la dirección (dirección efectiva) de donde se cogerá el dato que se deposita en la pila.

Rango de direcciones 15-8191 (Zona de memoria I/O y registros).

Codificación

1 Byte Opcode (h89).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Bring in en coma flotante 5001 6001 ──[FP]────────────────────────────────────────────────────────────────────(FP)── 0.00 00 0.00 00

Page 74: DCSLLL

4 Interpretación MS-DOS Loader

73

0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 A81389 271771 530000000000000000000000

Si la lógica precedente es 1, recoge dos palabras contiguas de 16 bits para formar el dato de 32 bits que contiene el valor en coma flotante y los deposita en la pila.

Rango de direcciones 4097-8191 (Zona de memoria de registros).

Codificación

1 Byte Opcode (hA8).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Codificación de datos en coma flotante (estándar IEEE)

El estándar IEEE codifica los números en coma flotante de la siguiente forma:

MMSB 1 MSB LSB LLSB2

31 30-24 23 22-16 15-8 7-0 EXPONENTE MANTISA

Figura 35. Codificación de números en coma flotante según estándar IEEE.

Número representado = (-1×bit31) × (1×20 + bit22×2-1 + .. + bit0×2-23) × 2(exponente-127)

Características:

- Mantisa: 23 bits + 1 bit signo. Aunque sean 23, en realidad son 24 pues hay un 1 implícito, ya que al trabajar siempre con un 1 delante de la coma prescindimos de él en la codificación, aunque no en las operaciones.

- Exponente: 8 bits con sesgo 127. Este tipo de codificación consiste en utilizar una codificación binaria normal, y desplazar el 0 al número 127.

Código Número

0 -127 1 -126

127 0 254 127 255 -

Tabla 12. Codificación de un número en sesgo a 127.

- Tamaño: 4 Bytes.

1 MMSB es la abreviación de Most Most Significant Byte. Representa el código

hexadecimal que contiene los 8 bits altos (posiciones 24 a 31) de una palabra de 32 bit. En este caso MSB contiene los bits de posiciones 16 a 23.

2 LLSB es la abreviación de Least Least Significant Byte. Representa el código hexadecimal que contiene los 8 bits bajos (posiciones 0 a 7) de una palabra de 32 bit. En este caso LSB contiene los bits de posiciones 8 a 15.

SIGNO MANTISA

Page 75: DCSLLL

4 Interpretación MS-DOS Loader

74

- Rango: (-3.4E-38 - 3.4E+38). El Rango viene determinado por las siguientes fórmulas:

Valor mínimo = 1×2-127 + 1×2-128 + .. + 1×2-142 ≈ 1.17 E-38

Valor máximo = 1×2127 + 1×2126 + .. + 1×2112 ≈ 3.40 E+38

La dirección indicada (N) contiene los Bytes MMSB y MSB, mientras que la dirección inferior (N-1) contiene los Bytes LSB y LLSB.

Send out 5001 6001 ──<B2>────────────────────────────────────────────────────────────────────(S2)── 0 0 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 891389 071771 530000000000000000000000

Si la lógica precedente es 1, recoge el último dato escrito en la pila y lo escribe en la dirección indicada. Si es 0 no se escribe ningún dato.

Rango de direcciones 15-8191 (zona de memoria I/O y registros). Si la dirección es menor de 4096 coge 16 direcciones consecutivas de la zona I/O escribiendo en N (dirección especificada) el bit de mayor peso y en la dirección N-15 el bit de menor peso del valor de 16 bits a escribir.

Al estar dentro del bloque de salto de una instrucción NSKD, durante el primer ciclo escribe un 0 en la dirección indicada.

Al estar dentro del bloque de salto de una instrucción NSKR o NSKD en posteriores ciclos al primero, se mantiene el valor existente en la dirección, por lo que si son modificadas en líneas no afectadas por el salto (situación anómala pues se intenta evitar utilizar la misma dirección como salida en líneas diferentes) o por edición del usuario, no vuelven a resetearse.

Puede ser forzada.

Codificación

1 Byte Opcode (h07).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Al ser forzado:

Forzado a ON Opcode (h37).

Forzado a OFF Opcode (h37).

Cuando se fuerza el MS-DOS Loader solicita el valor entero a escribir en memoria, tanto en el forzado a ON como a OFF. Como no guarda dicho valor en memoria de programa, sino que lo escribe directamente en el módulo de memoria de registros, si externamente se modifica el valor de la dirección, a pesar de que se indique que la instrucción está forzada, la próxima vez que se ejecute la instrucción no se restaurará el valor seleccionado.

Send out indirecto 5001 6001 ──[B2]────────────────────────────────────────────────────────────────────(I2)── 0 0 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 881389 061771 530000000000000000000000

Page 76: DCSLLL

4 Interpretación MS-DOS Loader

75

Si la lógica precedente es 1, recoge el último dato escrito en el stack para escribirlo en la dirección (dirección efectiva) contenida en la dirección indicada (dirección de referencia). Si es 0 no se escribe ningún dato.

Rango de direcciones 15-8191 (Zona de memoria I/O y registros).

Al estar dentro del bloque de salto de una instrucción NSKD, durante el primer ciclo escribe un 0 en la dirección (dirección efectiva).

Al estar dentro del bloque de salto de una instrucción NSKR o NSKD en posteriores ciclos al primero, se mantiene el valor existente en la dirección (dirección efectiva), por lo que si son modificadas en líneas no afectadas por el salto (situación anómala pues se intenta evitar utilizar la misma dirección como salida en líneas diferentes) o por edición del usuario, no vuelven a resetearse.

Codificación

1 Byte Opcode (h06).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Send out en coma flotante 5001 6001 ──[FP]────────────────────────────────────────────────────────────────────(FP)── 0.00 00 0.00 00 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 A81389 271771 530000000000000000000000

Si la lógica precedente es 1, recoge los dos últimos datos escritos en la pila para formar el dato de 32 bits que contiene el valor en coma flotante y los escribe en las direcciones especificadas.

Rango de direcciones 4097-8191 (Zona de memoria de registros).

La dirección indicada (N) contiene los Bytes MMSB y MSB, mientras que la dirección inferior (N-1) contiene los Bytes LSB y LLSB.

Al estar dentro del bloque de salto de una instrucción NSKD, durante el primer ciclo escribe un 0 en la dirección destino final (dirección efectiva).

Al estar dentro del bloque de salto de una instrucción NSKR o NSKD en posteriores ciclos al primero, la dirección destino final (dirección efectiva) mantiene el valor.

Codificación

1 Byte Opcode (h27).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Constante 6001 ──[K2]────────────────────────────────────────────────────────────────────(I2)── 5001 0 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 8B1389 061771 530000000000000000000000

Si la lógica precedente es 1, coge el valor entero codificado y lo deposita en la pila.

Si se trabaja con modelos de LM 620-25/35 que tienen una tabla de registros de 16+1 bits, en el caso de querer un número negativo es necesario utilizar una línea extra que escriba a uno el bit de signo de la dirección destino.

Page 77: DCSLLL

4 Interpretación MS-DOS Loader

76

Codificación

1 Byte Opcode (h8B).

2 Bytes Constante codificada en hexadecimal (MSB LSB).

Constante en coma flotante 6001 ──[FPK]───────────────────────────────────────────────────────────────────(FP)── 1.00 04 0.00 Constante codificada = 10000 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 9B4000 AB461C 271771 530000000000000000 6001 ──[FPK]───────────────────────────────────────────────────────────────────(FP)── -1.00 04 0.00 00 Constante codificada = -10000 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 9B4000 ABC61C 271771 530000000000000000

Si la lógica precedente es 1, coge el valor en coma flotante codificado en las líneas de programa y lo deposita en la pila.

Codificación

Según el estándar IEEE el número 10000 equivale a 46 1C 40 00.

La forma rápida de calcular sería:

46 1c 40 00 equivale a 0100 0110 0001 1100 0100 0000 0000 0000

signo: 0 +1

exponente: 100 0110 0 reordenados 1000 1100 8C 140 en sesgo 127 13

mantisa 1 + 001 1100 0100 0000 000 000 -> 9C4000 10240000

Valor = signo * mantisa * 2 exponente-24+1

Así el orden en que se ha codificado el número coma flotante en el código de programa es: 9B LSB LLSB AB MMSB MSB.

Se observa que a diferencia de los comandos de este grupo que se codifican con tres Bytes, al tener que incluir en el código de programa una constante en coma flotante, se necesitan dos bloques de tres Bytes.

1 Byte Opcode (h9B).

2 Bytes Constante codificada en hexadecimal (LSB LLSB).

1 Byte Opcode (hAB).

2 Bytes Constante codificada en hexadecimal (MMSB MSB).

Para codificar el 10000 consiste en ir dividiendo (número inicial mayor de 2) (o multiplicando si el numero inicial fuera menor de 1) el número inicial por 2 hasta que se obtiene un numero inferior a 2 superior a 1. El número de operaciones realizadas es el número del exponente (positivo si dividimos, negativo si multiplicamos). Así para 10000 tenemos que dividir 13 veces que en sesgo 127 equivale a 140. Luego multiplicaremos la parte decimal por dos, si el resultado es mayor de 1, apuntamos un uno y multiplicamos la parte decimal otra vez, si el resultado no llega a 1 apuntamos un cero y seguimos así hasta que no quede parte decimal.

Page 78: DCSLLL

4 Interpretación MS-DOS Loader

77

Así 10000 entre 2 x 13 = 1,220703125; 0,220703125 x 2 = 0,44140625 (0) x 2 = 0,8828125 (0) x2 = 1,765625 (1); 0,765625 x 2 = 1,53125 (1)… que equivale a una mantisa 0011…

PULL I/O 1001 2001 ──[PUL]───────────────────────────────────────────────────────────────────(PSH)─ 2 2 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 8023E9 8427D1 530000000000000000000000

Si la lógica precedente es 1, realiza una lectura de 1-8 datos de 16 bits de la tabla de memoria de estados E/S (acceso a módulos E/S analógicos) en direcciones correspondientes a tarjetas de entradas analógicas o especiales y los escribe en la pila en secuencia de N (dirección indicada) a N-8. En el caso de que la dirección especificada no corresponda a una tarjeta analógica o especial, el valor leído es 0. No se transfiere el bit de signo, por lo que éste no se ve afectado en el registro de destino.

Rango de direcciones 0-2047.

La lectura del valor de la dirección se realiza en tiempo real, no realizándose una captura al inicio del ciclo como ocurre con las entradas digitales.

Como es normal, no se puede capturar un bloque de direcciones mayor que el que permite la dirección de origen. Así, si se especifica la dirección 4, sólo se pueden leer 5 direcciones máximo (0 a 4).

Codificación

1 Byte Opcode (h80).

2 Bytes Número de la dirección codificada en hexadecimal (Especial).

De los 2 Bytes se requieren los 12 bits de menor peso para codificar la dirección de 0 a 4095.

Luego el número de registros (1 a 8) se codifica con los tres bits de mayor peso. Pero haciendo corresponder el número de registros de 1 a 8 con el rango de 0 a 7.

PULL Estados del sistema 2100 6001 ──[PUL]───────────────────────────────────────────────────────────────────(PSH)─ 7 3 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 802834 864771 530000000000000000000000

Instrucción válida para modelos de LM 620-06, 10, 15, 25 y 35. Para el resto de modelos consultar instrucción PULS.

Si la lógica precedente es 1, realiza una lectura de 1-8 datos de la tabla de memoria de estados del sistema y los escribe en la pila en secuencia de N (dirección indicada) a N-8.

Rango de direcciones 2048-4095.

Como accede a direcciones de 8 bits, para rellenar los registros de la pila de 16 bits, lee las direcciones de dos en dos. Por ello, si se indica un bloque de 8 se leen 16 direcciones.

Codificación

1 Byte Opcode (h80).

Page 79: DCSLLL

4 Interpretación MS-DOS Loader

78

2 Bytes Número de la dirección codificada en hexadecimal (Especial).

Se utiliza la misma codificación que en el apartado anterior.

PULL Registros 5001 6001 ──[PUL]───────────────────────────────────────────────────────────────────(PSH)─ 7 3 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 82C389 864771 530000000000000000000000

Si la lógica precedente es 1, realiza una lectura de 1-8 datos de la tabla de memoria de registros y los escribe en la pila en secuencia de N (dirección indicada) a N-8. Se transfiere el bit de signo.

Rango de direcciones 4096-8191.

Como es normal, no se puede capturar un bloque de un número de direcciones mayor que el que permite la dirección de origen. Así, si se especifica la dirección 4500, sólo se pueden leer 5 direcciones máximo (4096 a 4500).

Codificación

1 Byte Opcode (h82).

2 Bytes Número de la dirección codificada en hexadecimal (Especial).

Se hace corresponder el rango 4096-8191 con el 0-4095, de tal forma que se utiliza la misma codificación que en el apartado anterior.

PUSH I/O 1001 2001 ──[PUL]───────────────────────────────────────────────────────────────────(PSH)─ 2 2 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 8023E9 8427D1 530000000000000000000000

Si la lógica precedente es 1, lee 1 a 8 registros de la pila y los escribe en la tabla de memoria de estados E/S (acceso a módulos E/S analógicos) en secuencia de N (dirección indicada) a N-8. El bit de signo no se transfiere.

Rango de direcciones 0-2047.

Al estar dentro del bloque de salto de una instrucción NSKD, durante el primer ciclo escribe un 0 en todas las direcciones de destino.

Al estar dentro del bloque de salto de una instrucción NSKR o NSKD en posteriores ciclos al primero, se mantiene el valor existente en la dirección, por lo que si son modificadas en líneas no afectadas por el salto (situación anómala pues se intenta evitar utilizar la misma dirección como salida en líneas diferentes) o por edición del usuario, no vuelven a resetearse.

Codificación

1 Byte Opcode (h84).

2 Bytes Número de la dirección codificada en hexadecimal (Especial).

Misma codificación que instrucción “PULL I/O”

Page 80: DCSLLL

4 Interpretación MS-DOS Loader

79

PUSH Registros 5001 6001 ──[PUL]───────────────────────────────────────────────────────────────────(PSH)─ 7 3 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 82C389 864771 530000000000000000000000

Si la lógica precedente es 1, lee 1 a 8 registros de la pila y los escribe en la tabla de memoria de registros en secuencia de N (dirección indicada) a N-8. Se transfiere el bit de signo.

Rango de direcciones 4096-8191.

Al estar dentro del bloque de salto de una instrucción NSKD, durante el primer ciclo escribe un 0 en todas las direcciones de destino.

Al estar dentro del bloque de salto de una instrucción NSKR o NSKD en posteriores ciclos al primero, se mantiene el valor existente en la dirección, por lo que si son modificadas en líneas no afectadas por el salto (situación anómala pues se intenta evitar utilizar la misma dirección como salida en líneas diferentes) o por edición del usuario, no vuelven a resetearse.

Codificación

1 Byte Opcode (h84).

2 Bytes Número de la dirección codificada en hexadecimal (Especial).

Misma codificación que instrucción “PULL Registros”

PULS 3001 4102 ──[PULS]──────────────────────────────────────────────────────────────────(PSH)─ 7 7 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 81C3B9 862006 530000000000000000000000

Si la lógica precedente es 1, realiza una lectura de 1-8 datos de la tabla de memoria de estados del sistema y los escribe en la pila en secuencia de N (dirección indicada) a N-8.

Rango de direcciones 0-4095.

Como accede a direcciones de 8 bits, para rellenar los registros de la pila de 16 bits, lee las direcciones de dos en dos. Por ello, si se indica 8 registros y la dirección 15, se leen las 16 primeras direcciones.

Codificación

1 Byte Opcode (h81).

2 Bytes Número de la dirección codificada en hexadecimal (Especial).

La codificación es similar al caso anterior, solo que resta el valor h800 de los bits de dirección, así la dirección 3001 (hBB9) menos h800 es h3B9.

Instrucciones de manipulación de datos y condicionantes lógicos La siguiente línea de programa resume el funcionamiento

Page 81: DCSLLL

4 Interpretación MS-DOS Loader

80

1001 1002 1004 6001 ───] [────[K2]──┬──] [────[K2]──┬───] [───────────────────────────────────(S2)── 1 │ 2 │ VER TABLA │ │ │ 1003 │ └──] [────[K2]──┴ 3

1001 1002 1003 1004 6001 FALSE X X X NO CARGA DATO

X X X FALSE NO CARGA DATO TRUE FALSE FALSE TRUE NO CARGA DATO TRUE TRUE FALSE TRUE 2 TRUE X TRUE TRUE 3

Tabla 13. Instrucciones de manipulación de datos y condicionantes lógicos

El stack y las instrucciones de manipulación de datos

Funcionamiento de PULL, PUSH

Si la dirección 1000 contenía el valor 1005 y la dirección 1001 el valor 1006, tras ejecutar la siguiente instrucción, la dirección 2000 contenía el valor 1005 (dirección 1000) y la dirección 2001 contenía el valor 1006 (dirección 1001). 1001 2001 ──[PUL]───────────────────────────────────────────────────────────────────(PSH)─ 2 2 1006 1005

Sabiendo que ambas leen y escriben comenzando por la dirección más alta, no queda otra solución más que la pila en este caso sigue un comportamiento FIFO (first-in, first-out) en el que el primer elemento en entrar es el primero en salir.

Funcionamiento de B2, PUSH 1001 1000 2001 ──[B2]───────[B2]─────────────────────────────────────────────────────────(PSH)─ 1006 1005 2 1006 1005

De igual forma se obtiene un comportamiento FIFO.

Funcionamiento de B2, S2 1001 1000 2001 ──[B2]───────[B2]─────────────────────────────────────────────────────────(S2)─ 1006 1005 1005

Sin embargo, en este caso, se aprecia que el elemento S2 (Bring in) hace que la pila siga un comportamiento LIFO (last-in, first-out), para el que el último elemento en entrar es el primero en salir.

4.2.3.10. Instrucciones de comparación Son utilizadas para comparar dos valores obtenidos a partir de instrucciones de

manipulación de datos.

Igual a 3001 ──[K2]─────]=[────[K2]─────────────────────────────────────────────────────( )── 1001 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 087FFF 8B07D1 C40BB9 530000000000

Page 82: DCSLLL

4 Interpretación MS-DOS Loader

81

Si la lógica precedente es 1, realiza la comparación entre los dos operandos. Si son iguales permite seguir la secuencia en las instrucciones siguientes.

Tiene en cuenta el signo a la hora de realizar la comparación.

Codificación

1 Byte Opcode (h08).

2 Bytes Código (h7F FF).

Menor que (con signo) 3001 ──[K2]─────]<[────[K2]─────────────────────────────────────────────────────( )── 1001 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 097FFF 8B07D1 C40BB9 530000000000

Si la lógica precedente es 1, realiza la comparación entre los dos operandos. Si el primero es menor que el segundo, permite seguir la secuencia en las instrucciones siguientes.

Tiene en cuenta el signo a la hora de realizar la comparación.

Codificación

1 Byte Opcode (h09).

2 Bytes Código (h7F FF).

Mayor que (con signo) 3001 ──[K2]─────]>[────[K2]─────────────────────────────────────────────────────( )── 1001 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 0A7FFF 8B07D1 C40BB9 530000000000

Si la lógica precedente es 1, realiza la comparación entre los dos operandos. Si el primero es mayor que el segundo, permite seguir la secuencia en las instrucciones siguientes.

Tiene en cuenta el signo a la hora de realizar la comparación.

Codificación

1 Byte Opcode (h0A).

2 Bytes Código (h7F FF).

Menor que (sin signo) 3001 ──[K2]─────]<[─────]<[────[K2]─────────────────────────────────────────────( )── 1001 2001 0A000080001000080500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C05 8B03E9 097FFF 097FFF 8B07D1 C40BB9 530000

De acuerdo al manual de programación, si la lógica precedente es 1, realiza la comparación entre los dos operandos. Si el valor absoluto del primero es menor que el del segundo, permite seguir la secuencia en las instrucciones siguientes. 6001 ──[K2]─────]<[────]<[─────[K2]─────────────────────────────────────────────( )── -4 3

Page 83: DCSLLL

4 Interpretación MS-DOS Loader

82

Resultado: TRUE cuando se esperaba FALSE.

Se concluye que la combinación de operadores de comparación para formar las instrucciones “Menor que (sin signo)”, “Mayor que (sin signo)” “No igual a” no funcionan de la forma esperada

Codificación

1 Byte Opcode (h09).

2 Bytes Código (h7F FF).

1 Byte Opcode (h09).

2 Bytes Código (h7F FF).

Mayor que (sin signo) 3001 ──[K2]─────]>[─────]>[────[K2]─────────────────────────────────────────────( )── 1001 2001 0A000080001000080500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C05 8B03E9 0A7FFF 0A7FFF 8B07D1 C40BB9 530000

De acuerdo al manual de programación si la lógica precedente es 1, realiza la comparación entre los dos operandos. Si el valor absoluto del primero es mayor que el del segundo, permite seguir la secuencia en las instrucciones siguientes.

El funcionamiento real no coincide con el descrito, tal y como ocurría en la instrucción anterior.

Codificación

1 Byte Opcode (h0A).

2 Bytes Código (h7F FF).

1 Byte Opcode (h0A).

2 Bytes Código (h7F FF).

No igual a 3001 ──[K2]─────]<[─────]>[────[K2]─────────────────────────────────────────────( )── 1001 2001 0A000080001000080500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C05 8B03E9 097FFF 0A7FFF 8B07D1 C40BB9 530000

De acuerdo al manual de programación si la lógica precedente es 1, realiza la comparación entre los dos operandos. Si son diferentes, permite seguir la secuencia en las instrucciones siguientes.

El funcionamiento real no coincide con el descrito, tal y como ocurría en la instrucción anterior.

Codificación

1 Byte Opcode (h09).

2 Bytes Código (h7F FF).

1 Byte Opcode (h0A).

2 Bytes Código (h7F FF).

Page 84: DCSLLL

4 Interpretación MS-DOS Loader

83

Menor o igual, Mayor o igual. Además de las combinaciones anteriores, de acuerdo al manual también se pueden

combinar los elementos anteriores para formar las siguientes instrucciones:

< + = Menor o igual

> + = Mayor o igual

Sin embargo, al realizar las pruebas con un programa corriendo sobre el LM, se obtuvieron los siguientes resultados: 6001 ──[K2]─────]<[────]=[─────[K2]─────────────────────────────────────────────( )── 6 10

Resultado: FALSE cuando se esperaba TRUE. 6001 ──[K2]─────]=[────]<[─────[K2]─────────────────────────────────────────────( )── 6 10

Resultado: TRUE.

Se concluye que la combinación de operadores de comparación no funciona correctamente. Se observa que en realidad lo que el procesador hace es presentar el resultado de la operación indicada por el último operador, pues es la última evaluada al realizar una lectura secuencial.

Prueba de cero 1001 3001 ───]Z[─────────────────────────────────────────────────────────────────────( )── 0 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 8D03E9 C40BB9 530000000000000000000000

Si la lógica precedente es 1 y el valor contenido en la dirección indicada es cero, permite seguir la secuencia en las instrucciones siguientes.

Rango de direcciones 15-8191. Se comporta igual que la instrucción “Bring in”.

Codificación

1 Byte Opcode (h8D).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

El stack y las instrucciones de comparación El funcionamiento de las instrucciones de comparación trabajando en combinación con

instrucciones de contactos y bobinas no tiene gran misterio, sin embargo, existe la incógnita del comportamiento en el caso de trabajar en combinación con elementos S2 (send out). 6001 ──[K2]─────]<[────[K2]────────────────────────────────────────────────────(S2)── 6 8

Resultado: 6 6001 ──[K2]─────]>[────[K2]────────────────────────────────────────────────────(S2)── 6 8

Resultado: NO CARGA DATO

Se aprecia, que si no se cumple la comparación, la instrucción S2 no carga ningún dato.

Page 85: DCSLLL

4 Interpretación MS-DOS Loader

84

En contra de lo esperado, el valor recuperado por la instrucción S2 (Bring in) es el del primer operando.

El ejemplo anterior, explica que la expresión de la línea de programa siguiente sea uno, en caso de que el primer elemento sea mayor que el segundo y menor que el tercero. 6001 ──[K2]─────]>[────[K2]─────]<[──── [K2]───────────────────────────────────( )── 15 1 10

Resultado: FALSE

El resultado FALSE se explica en cuanto el valor comparado con 10 sigue siendo 15 (primer operando) y no 1.

4.2.3.11. Instrucciones matemáticas Se escriben entre dos elementos de datos, sobre los que se realiza la operación

matemática solicitada. El resultado se almacena en la pila para posteriores transferencias a la tabla de estados I/O o de registros.

El procesador del LM es capaz de realizar las siguientes operaciones matemáticas con números de formato entero y coma flotante: Suma, resta, multiplicación, división.

Palabra de error/estado Los errores que se pueden producir en cada una de las operaciones se agrupan en un

registro de 16 bits donde, el LSB está dedicado a operaciones con número en formato entero y el MSB está dedicado a operaciones con números en formato coma flotante.

Como el modelo en estudio 620-35 no soporta operaciones en coma flotante, aunque se listan no se van a describir los bits del Byte dedicado a operaciones en coma flotante:

• Bit 0 – C (Carry). Contiene un 1 cuando el resultado de una suma o resta excede el valor máximo de un registro de 16 bits (65535)

• Bit 1 – V (signed overflow) Contiene un uno cuando en una operación en complemento a dos, un overflow provoca un cambio de signo no correcto. Como el 620-35 no trabaja en complemento a dos sino con registros de 16 bits + 1 bit de signo, este bit no se ve afectado.

• Bit 2 – Z (Zero) Contiene un 1 cuando el resultado de una operación es cero.

• Bit 3 – N (Negative) Contiene un 1 cuando el resultado de una operación es negativo.

• Bit 4 – RV (Reserved for system)

• Bit 5 - /0 (Integer divide-by-zero) Contiene un 1 cuando se intenta dividir un entero por cero.

• Bit 6,7,8,9,10 – X (Not used)

• Bit 11 – BCD (BCD Error)

• Bit 12 – IO (Invalid operador)

• Bit 13 – F/0 (Floating point divide-by-zero)

• Bit 14 – FU (Floating point underflow)

• Bit 15 – FO (Floating point overflow)

Page 86: DCSLLL

4 Interpretación MS-DOS Loader

85

Suma 3001 ──[K2]─────[+]────[K2]─────────────────────────────────────────────────────(S2)── 1001 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 0E7FFF 8B07D1 070BB9 530000000000

Si la lógica precedente es 1, realiza la suma entre los dos operandos de 16 bits, depositando en la pila un dato de 16 bits conteniendo el resultado.

Tiene en cuenta el signo a la hora de realizar la operación.

En caso de que el dato resultante exceda del rango -65535 a 65535, el bit de carry de la palabra de error, pasa a ser uno. El valor de este bit puede ser obtenido programando una bobina de salida como elemento de salida de la línea que contiene la operación.

Codificación

1 Byte Opcode (h0E).

2 Bytes Código (h7F FF).

Se deben de actualizar los siguientes bits de la palabra de estado: Carry (0), Zero (2), Negative (3).

Suma con dirección de error 5001 3001 ──[K2]─────[+]────[K2]─────────────────────────────────────────────────────(S2)── 1001 0 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 0E1389 8B07D1 070BB9 530000000000

Esta instrucción sólo está permitida por los modelos 620-11,14 y 16, por lo que no va a ser implementada.

Si la lógica precedente es 1, realiza la suma entre los dos operandos de 16 bits, depositando en la pila un dato de 16 bits conteniendo el resultado. La palabra de error de la operación realizada se escribe en la dirección indicada.

Tiene en cuenta el signo a la hora de realizar la operación.

Rango de direcciones de error de 15 a 8191.

Codificación

1 Byte Opcode (h0E).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Resta 3001 ──[K2]─────[-]────[K2]─────────────────────────────────────────────────────(S2)── 1001 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 0D7FFF 8B07D1 740BB9 530000000000

Si la lógica precedente es 1, realiza la resta entre los dos operandos de 16 bits, depositando en la pila un dato de 16 bits conteniendo el resultado.

Tiene en cuenta el signo a la hora de realizar la operación.

Page 87: DCSLLL

4 Interpretación MS-DOS Loader

86

En caso de que el dato resultante exceda del rango -65535 a 65535, el bit de carry de la palabra de error, pasa a ser uno. El valor de este bit puede ser obtenido programando una bobina de salida como elemento de salida de la línea que contiene la operación.

Codificación

1 Byte Opcode (h0D).

2 Bytes Código (h7F FF).

Se deben de actualizar los siguientes bits de la palabra de estado: Carry (0), Zero (2), Negative (3).

Resta con dirección de error 5001 3001 ──[K2]─────[-]────[K2]─────────────────────────────────────────────────────(S2)── 1001 0 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 0D1389 8B07D1 070BB9 530000000000

Esta instrucción sólo está permitida por los modelos 620-11,14 y 16, por lo que no va a ser implementada.

Si la lógica precedente es 1, realiza la resta entre los dos operandos de 16 bits, depositando en la pila un dato de 16 bits conteniendo el resultado. La palabra de error de la operación realizada se escribe en la dirección indicada.

Tiene en cuenta el signo a la hora de realizar la operación.

Rango de direcciones de error de 15 a 8191.

Codificación

1 Byte Opcode (h0D).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Multiplicación 3001 ──[K2]─────[*]────[K2]─────────────────────────────────────────────────────(S2)── 1001 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 0C7FFF 8B07D1 070BB9 530000000000

Si la lógica precedente es 1, realiza la multiplicación entre los dos operandos de 16 bits, depositando en la pila dos datos de 16 bits conteniendo el resultado.

Tiene en cuenta el signo a la hora de realizar la operación.

El primer dato escrito contiene los bytes MMSB y MSB, conteniendo el bit de signo el bit de carry.

El segundo dato contiene los bytes LSB y LLSB, conteniendo el bit de signo el signo del resultado.

En caso de que el dato resultante exceda del rango -65535 a 65535, el bit de carry de la palabra de error, pasa a ser uno. El valor de este bit puede ser obtenido programando una bobina de salida como elemento de salida de la línea que contiene la operación.

Codificación

1 Byte Opcode (h0C).

Page 88: DCSLLL

4 Interpretación MS-DOS Loader

87

2 Bytes Código (h7F FF).

Se deben de actualizar los siguientes bits de la palabra de estado: Carry (0), Zero (2), Negative (3).

Multiplicación con dirección de error 5001 3001 ──[K2]─────[*]────[K2]─────────────────────────────────────────────────────(S2)── 1001 0 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 0C1389 8B07D1 070BB9 530000000000

Esta instrucción sólo está permitida por los modelos 620-11,14 y 16, por lo que no va a ser implementada.

Si la lógica precedente es 1, realiza la multiplicación entre los dos operandos de 16 bits, depositando en la pila dos datos de 16 bits conteniendo el resultado. La palabra de error de la operación realizada se escribe en la dirección indicada.

Tiene en cuenta el signo a la hora de realizar la operación.

Rango de direcciones de error de 15 a 8191.

Codificación

1 Byte Opcode (h0C).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

División 3001 ──[K2]─────[K2]─────[/]────[K2]────────────────────────────────────────────(S2)── 0 1001 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B00000 8B03E9 0B7FFF 8B07D1 070BB9 530000000000

Si la lógica precedente es 1, realiza la división entre un dividendo de 32 bits y un divisor de 16 bits, depositando en la pila dos datos de 16 bits conteniendo el resto y el cociente.

Tiene en cuenta el signo a la hora de realizar la operación.

El primer dato escrito contiene el resto, conteniendo el bit de signo el bit de carry.

El segundo dato contiene el cociente, conteniendo el bit de signo el signo del resultado.

En caso de que el dato resultante exceda del rango -65535 a 65535, el bit de “carry” de la palabra de error, pasa a ser uno. El valor de este bit puede ser obtenido programando una bobina de salida como elemento de salida de la línea que contiene la operación.

Si se intenta dividir por cero, a parte de ponerse a uno el bit “Integer divide-by-zero”, los dos valores escritos en la pila son cero.

Codificación

1 Byte Opcode (h0B).

2 Bytes Código (h7F FF).

Se deben de actualizar los siguientes bits de la palabra de estado: Carry (0), Zero (2), Negative (3), Integer divide-by-zero (5).

Page 89: DCSLLL

4 Interpretación MS-DOS Loader

88

División con dirección de error 5001 3001 ──[K2]─────[K2]─────[/]────[K2]───────────────────────────────────────────(S2)── 0 1001 0 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B0000 8B03E9 0B1389 8B07D1 070BB9 530000000000

Esta instrucción sólo está permitida por los modelos 620-11,14 y 16, por lo que no va a ser implementada.

Si la lógica precedente es 1, realiza la división entre un dividendo de 32 bits y un divisor de 16 bits, depositando en la pila dos datos de 16 bits conteniendo el resto y el cociente. La palabra de error de la operación realizada se escribe en la dirección indicada.

Tiene en cuenta el signo a la hora de realizar la operación.

Rango de direcciones de error de 15 a 8191.

Codificación

1 Byte Opcode (h0B).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

El stack y las instrucciones matemáticas

El stack y una única operación

En las siguientes instrucciones, para poder determinar como se almacenan los datos en la pila, en vez de realizar un PUSH de dos elementos, se ha realizado un PUSH de 8, pudiendo observar así los datos anteriores contenidos en la pila. 6001 ──[K2]─────]+[────[K2]────────────────────────────────────────────────────(S2)── 11000 3 11003 6001 ──[K2]─────]+[────[K2]───────────────────────────────────────────────────(PSH)── 3 33000 8 33003 0 3 33000 1194 1877 1877 1194 6001 ──[K2]─────]-[────[K2]────────────────────────────────────────────────────(S2)── 11000 3 10997 6001 ──[K2]─────]-[────[K2]───────────────────────────────────────────────────(PSH)── 3 33000 8 -32997 0 3 33000 1194 1877 1877 1194 6001 ──[K2]─────]*[────[K2]────────────────────────────────────────────────────(S2)── 11000 3 33000

Resultado 0 Primer operando Segundo operando Datos de instrucciones anteriores

Resultado 0 Primer operando Segundo operando Datos de instrucciones anteriores

Page 90: DCSLLL

4 Interpretación MS-DOS Loader

89

6001 ──[K2]─────]*[────[K2]───────────────────────────────────────────────────(PSH)── 3 33000 8 -1 33464 3 33000 1194 1877 1877 1194 6001 ──[K2]─────[K2]─────]/[────[K2]───────────────────────────────────────────(S2)── 0 11000 3 3666 6001 ──[K2]─────[K2]─────]/[────[K2]──────────────────────────────────────────(PSH)── 0 11000 3 2 2 3666 6001 ──[K2]─────]/[────[K2]───────────────────────────────────────────────────(PSH)── 3 33000 8 3 0 3 33000 1194 1877 1877 1194

Tal y como se dedujo en el capítulo 4.2.3.9 Instrucciones de manipulación de datos, las instrucciones K2, B2, PULL escriben los datos en la pila a medida que se van leyendo.

Sin embargo, el resultado de las operaciones matemáticas se almacena en las dos primeras posiciones de la pila, y no en el primer registro libre que señala el puntero. Estas dos primeras posiciones parecen estar inhabilitadas hasta que se produce la primera operación de la línea.

Realizar una operación reinicializa el puntero en la tabla, no así el cambio de línea pues se permite encadenar operaciones de una línea con otra, situándolo en el último dato escrito con el resultado:

• Primer registro si operación de suma o resta.

• Segundo registro si operación de multiplicación o división.

Así se explica que la instrucción S2 (Bring in), lea el cociente si es una división, o el registro LSB LLSB si es una multiplicación.

El stack y operaciones encadenadas

En los siguientes ejemplos se han representado los cambios que produce evaluar cada instrucción, de acuerdo a como se cree que evoluciona el sistema.

La celda sombreada indica la posición del último registro válido apuntado por el puntero de pila, que será el dato leído por la instrucción S2 (bring in).

MMSB MSB + Carry LSB LLSB + Signo Primer operando Segundo operando Datos de instrucciones anteriores

Resto + Carry Cociente + Signo Primer operando Segundo operando Datos de instrucciones anteriores

Page 91: DCSLLL

4 Interpretación MS-DOS Loader

90

6001 ──[K2]─────[K2]─────[K2]─────]*[────[K2]────]/[────[K2]──────────────────(PSH)── 1 2 3 33000 4 8 0 24750 4 2 3 33000 1877 1194 6001 ──[K2]─────]-[─────[K2]─────]+[────[K2]─────]/[────[K2]───────────────────(PSH)── 45000 33000 3 3 8 0 4001 45000 33000 1194 1877 1877 1194 6001 ──[K2]─────]-[────[K2]─────]*[────[K2]─────]+[────[K2]───────────────────(PSH)── 45000 33000 3 5 8 36005 36000 5 33000 1194 1877 1877 1194

Como se puede apreciar, los elementos se evalúan en el mismo orden en que se evalúa la lógica booleana. 6001 ├─[K2]─────]-[────[K2]──┬──]*[────[K2]───────────────────────────────────(PSH)── │45000 33000 │ 3 8 │ │ 0 │ │ 34500 ├──]-[─────[K2]─────────┴ 45000 500 33000 1194 1877 1877 1194

45000 – 33000 =12000 – 500 = 11500 * 3 = 34500

Instrucciones matemáticas y condicionantes lógicos 6001 ───] [────[K2]─────]-[────[K2]────────────────────────────────────────────(S2)── TRUE 1 1000 -999 6001 ───] [────[K2]─────]-[────[K2]────────────────────────────────────────────(S2)── FALSE 1 1000

Resultado: No carga dato.

El funcionamiento es igual al de las instrucciones de manipulación de datos trabajando con condicionantes lógicos. El condicionante lógico determina si se realiza o no la operación. 6001 ──[K2]─────]-[────[K2]─────] [────────────────────────────────────────────(S2)── 1 1000 TRUE -999 6001 ──[K2]─────]-[────[K2]─────] [────────────────────────────────────────────(S2)── 1 1000 FALSE -999

1 X

1 2 3

1 2 X

X 123

33000

-133464

X

423

33000

024750

X

45000 X

120000

4500033000

4500033000

X

120033

4500033000

X

04001

X

45000 X

120000

4500033000

4500033000

X

036000

533000

X

3600536000

X

Page 92: DCSLLL

4 Interpretación MS-DOS Loader

91

Sin embargo, al trabajar con contactos posteriores a la operación, una vez la operación ha sido ejecutada el resultado es cargado en la dirección de salida dando igual el valor del condicionante lógico. 6001 ├─[K2]─────]-[────[K2]──┬──]*[────[K2]────────────────────────────────────(S2)── │45000 33000 │ 3 VER TABLA │ │ │ 1001 │ ├──] [─────]-[─────[K2]─┴ 500

1001 6001 TRUE 34500 FALSE 36000

Tabla 14. Instrucciones matemáticas y condicionantes lógicos

Otras pruebas

Las dos líneas siguientes demuestran como se incluye el signo del resultado en el registro LSB LLSB. 6001 ──[K2]─────]*[────[K2]────────────────────────────────────────────────────(S2)── 33000 2 464 6001 ──[K2]─────]*[────[K2]────────────────────────────────────────────────────(S2 )── -33000 2 -464

Las dos líneas siguientes demuestran como se almacena el valor del bit de carry en el registro MMSB MSB. 6001 ──[K2]─────]*[────[K2]───────────────────────────────────────────────────(PSH)── 33000 2 -1 464 6001 ──[K2]─────]*[────[K2]───────────────────────────────────────────────────(PSH)── -33000 2 -1 -464

Si se ha producido una operación matemática en la línea, se guarda el bit de carry en la salida digital asignada a esa línea. 6001 ──[K2]─────]*[────[K2]─────────────────────────────────────────────────────( )── -33000 2 TRUE 6001 ──[K2]─────]*[────[K2]─────────────────────────────────────────────────────( )── -33000 1 FALSE

Las tres líneas siguientes fueron programadas una detrás de otra. Con ellas se demuestra:

• La pila se reinicia al escribir el resultado de una nueva operación, y no por cambiar de línea.

• Una sucesión de instrucciones PUSH va extrayendo los datos de la pila, sin embargo, los datos no son borrados, sino que se desplaza el puntero para avanzar por los registros.

Page 93: DCSLLL

4 Interpretación MS-DOS Loader

92

6001 ──[K2]─────]-[────[K2]─────]+[────[K2]─────]/[────[K2]───────────────────(PSH)── 44000 33000 3 3 8 2 3667 44000 33000 1194 1877 1877 1194 6001 ──[K2]─────]-[────[K2]─────]+[────[K2]─────]/[────[K2]───────────────────(PSH)── 44000 33000 3 3 2 2 3667 6001 ─────────────────────────────────────────────────────────────────────────(PSH)── 2 44000 33000

4.2.3.12. Instrucciones de operadores lógicos Son utilizados para realizar operaciones de lógica simple en dos palabras de 16 bits.

Como ninguna de estas instrucciones está recogida en el set de instrucciones del modelo 620-35, no van a ser estudiadas en profundidad, al estar sólo contempladas en la parte de visualización y no en la de simulación.

AND 3001 ──[K2]─────[&]────[K2]─────────────────────────────────────────────────────(S2)── 1001 2001 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 2C7FFF 8B07D1 070BB9 530000000000

Codificación

1 Byte Opcode (h2C).

2 Bytes Código (h7F FF).

OR 3001 ──[K2]────[OR]────[K2]────────────────────────────────────────────────────(S2)── 1001 2001 0 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 2E7FFF 8B07D1 070BB9 530000000000

Codificación

1 Byte Opcode (h2E).

2 Bytes Código (h7F FF).

OR exclusiva 3001 ──[K2]────[XOR]───[K2]────────────────────────────────────────────────────(S2)── 1001 2001 0 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 8B03E9 3E7FFF 8B07D1 070BB9 530000000000

Page 94: DCSLLL

4 Interpretación MS-DOS Loader

93

Codificación

1 Byte Opcode (h3E).

2 Bytes Código (h7F FF).

Resumen Se observa que todos los comandos de este grupo se codifican con tres grupos de tres

bytes:

• Primer grupo para identificar el primer operando a partir de una de las instrucciones de manipulación de datos.

• Segundo grupo para identificar el operador.

• Tercer grupo para identificar segundo operando a partir de una de las instrucciones de manipulación de datos.

4.2.3.13. Instrucciones de conversión de datos Proveen un método para la conversión de datos de un formato a otro.

El procesador del LM es capaz de realizar las siguientes operaciones de conversión con números de formato entero y coma flotante: raíz cuadrada, valor absoluto, conversión coma flotante a entero, conversión entero a BCD, conversión BCD a entero.

Como ninguna de estas instrucciones está recogida en el set de instrucciones del modelo 620-35, no van a ser estudiadas en profundidad, al estar sólo contempladas en la parte de visualización y no en la de simulación.

Conversión de binario a BCD sin/con dirección de error 5001 6001 ──[K2]────[BCD]───────────────────────────────────────────────────────────(S2)── 16 0 0 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 8B0010 1F1389 071771 530000000000000000

Convierte el número binario, obtenido por una instrucción de manipulación de datos o de cálculo precedente, en un número BCD de cuatro dígitos comprendidos entre 0 y 9999.

Si se ha especificado dirección de error, se escribe el registro de error/estado en la misma.

Codificación

1 Byte Opcode (h1F).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB) donde escribir el registro de error/estado. Código h7FFF si no se utiliza dirección de error.

Conversión de BCD a binario sin/con dirección de error 5001 6001 ──[K2]────[BIN]───────────────────────────────────────────────────────────(S2)── 16 0 0 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 8B0010 0F1389 071771 530000000000000000

Convierte el número BCD de cuatro dígitos comprendidos entre 0 y 9999, obtenido por una instrucción de manipulación de datos o de cálculo precedente, en un número binario.

Page 95: DCSLLL

4 Interpretación MS-DOS Loader

94

Si se ha especificado dirección de error, se escribe el registro de error/estado en la misma.

Codificación

1 Byte Opcode (h0F).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB) donde escribir el registro de error/estado. Código h7FFF si no se utiliza dirección de error.

Conversión de entero a coma flotante 6001 ──[K2]────[FLT]───────────────────────────────────────────────────────────(FP)── 16 0.00 00 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 8B0010 2F7FFF 271771 530000000000000000

Convierte el número entero de 16 bits con signo, obtenido por una instrucción de manipulación de datos o de cálculo precedente, en un número en coma flotante de 32 bits.

El programa Loader no pregunta por la dirección de error con esta instrucción aunque según el manual tendría que hacerlo. Debe de ser porque en las instrucciones anteriores el único error posible es que se produzca un desbordamiento en la conversión, error imposible en la conversión actual.

Codificación

1 Byte Opcode (h2F).

2 Bytes Código (h7FFF).

Conversión de coma flotante a entero sin/con dirección de error 5001 6001 ──[FPK]───[INT]───────────────────────────────────────────────────────────(S2)── 1.00 04 0 0 0A000080001000080400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C04 9B4000 AB461C 3F1389 071771 530000000000

Convierte el número en coma flotante de 32 bits, obtenido por una instrucción de manipulación de datos o de cálculo precedente, en un número entero de 16 bits con signo.

Si se ha especificado dirección de error se escribe el registro de error/estado en la misma.

Codificación

1 Byte Opcode (h3F).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB) donde escribir el registro de error/estado. Código h7FFF si no se utiliza dirección de error.

Conversión a valor absoluto sin/con dirección de error 4001 5001 6001 ──[B2]────[ABS]───────────────────────────────────────────────────────────(S2)── 0 0 0 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 880FA1 1C1389 071771 530000000000000000

Convierte el número entero de 16 bits con signo, obtenido por una instrucción de manipulación de datos o de cálculo precedente, en un número entero de 16 bits positivo.

Page 96: DCSLLL

4 Interpretación MS-DOS Loader

95

Si se ha especificado dirección de error se escribe el registro de error/estado en la misma.

Codificación

1 Byte Opcode (h1C).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB) donde escribir el registro de error/estado. Código h7FFF si no se utiliza dirección de error.

Conversión a raíz cuadrada sin/con dirección de error 7001 5001 6001 ──[FP]────[SQRT]──────────────────────────────────────────────────────────(FP)── 0.00 00 0 0.00 00 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 A81B59 2D1389 271771 530000000000000000

Calcula la raíz cuadrada del número en coma flotante positivo de 32 bits con signo obtenido por una instrucción de manipulación de datos o de cálculo.

Si se ha especificado dirección de error, se escribe el registro de error/estado en la misma.

Codificación

1 Byte Opcode (h2D).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB). Código h7FFF si no se utiliza dirección de error.

Negación 6001 ──[K2]────[NEG]───────────────────────────────────────────────────────────(S2)── 16 0 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 8B0010 1E7FFF 071771 530000000000000000

Calcula el complemento a dos del número entero de 16 bits con signo obtenido por una instrucción de manipulación de datos o de cálculo .

Codificación

1 Byte Opcode (h1E).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

NOT 6001 ──[K2]────[NOT]───────────────────────────────────────────────────────────(S2)── 16 0 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 8B0010 1D7FFF 071771 530000000000000000

Calcula el complemento a uno del número entero de 16 bits con signo obtenido por una instrucción de manipulación de datos o de cálculo.

Codificación

1 Byte Opcode (h1E).

2 Bytes Número de la dirección codificada en hexadecimal (MSB LSB).

Page 97: DCSLLL

4 Interpretación MS-DOS Loader

96

4.2.3.14. Instrucciones de secuenciador Permite el acceso indexado a una zona de direcciones de la tabla de registros.

Debido a la poca utilización y alta complejidad de estas instrucciones se decidió no incluirlas ni en la parte de visualización ni en la de simulación del proyecto, por lo que su mención aquí es para poder contemplar las posibilidades totales que ofrece un Logic Manager.

4.2.3.15. Instrucciones de matrices Permite formar matrices con los datos contenidos en direcciones de las tablas de estados

E/S o de registros y trabajar con ellos.

Se disponen de instrucciones que permiten:

• Cambiar el estado de las direcciones dentro de una matriz: Generar matriz 0 y generar matriz 1.

• Modificar el contenido de una matriz y desplazar el resultado a una segunda posición de la matriz: Mover matriz e insertar matriz.

• Realizar una operación entre dos matrices y situar el resultado en una tercera: OR, XOR, AND y comparar.

Debido a la poca utilización y alta complejidad de estas instrucciones se decidió no incluirlas ni en la parte de visualización ni en la de simulación del proyecto, por lo que se mencionan aquí únicamente para poder contemplar las posibilidades totales que ofrece un Logic Manager.

4.2.3.16. Instrucciones diversas

DLA 1001 2001 ───] [────[DLA]────────────────────────────────────────────────────────────( )── 250 0A000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 C803E9 CF00FA C407D1 530000000000000000

Si la lógica precedente es 1, pausa el scan del programa por un periodo de tiempo definido por el usuario.

Rango de valores de 0 a 65535 microsegundos.

Codificación

1 Byte Opcode (hCF).

2 Bytes Número de microsegundos en hexadecimal (MSB LSB).

No operando 2001 ───NOP─────────────────────────────────────────────────────────────────────( )── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 FF7FFE C407D1 530000000000000000000000

No realiza función alguna, comportándose como un cortocircuito.

Page 98: DCSLLL

4 Interpretación MS-DOS Loader

97

Codificación

Aunque hFF7FFE es el código que aparece si se escribe esta instrucción en el programa, en ciertos casos en los que no se ha llegado a determinar un patrón, aparecen comandos NOP en el que el opcode es 00 + dos bytes con cualquier valor.

1 Byte Opcode (hFF).

2 Bytes Código (h7FFE).

O

1 Byte Opcode (h00).

2 Bytes Código (h####).

Exploración estados de entradas 2001 ───ISS─────────────────────────────────────────────────────────────────────( )── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 8F7FFF C407D1 530000000000000000000000

Provoca la actualización de la tabla de estados E/S a partir de los datos contenidos en las tarjetas de E/S físicas.

No está condicionada por la lógica precedente. Es ejecutada siempre que es leída.

Codificación

1 Byte Opcode (h8F).

2 Bytes Código (h7FFF).

4.2.3.17. Instrucciones no descritas en el manual

Inversor lógico 2001 ───]o[─────────────────────────────────────────────────────────────────────( )── 0A000080001000080200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C02 CB7FFF C407D1 530000000000000000000000

Invierte el resultado de la lógica precedente.

Codificación

1 Byte Opcode (hCB).

2 Bytes Código (h7FFF).

4.2.3.18. Interconexión de elementos Una vez estudiadas todas las instrucciones de forma individual, es necesario estudiar

como se codifica su interconexión para formar, por ejemplo, las ramas paralelo que pueden contener las líneas de lógica.

Elementos en serie 1001 1002 1003 1004 1005 1006 1007 1008 1009 2001 ───] [─────] [─────] [─────] [─────] [─────] [─────] [─────] [─────] [─────( )── 0A000080001000080A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C0A C803E9 C803EA C803EB C803EC C803ED C803EE C803EF C803F0 C803F1 C407D1 53000000

Una interconexión serie no necesita códigos adicionales, basta con que los elementos se escriban uno detrás de otro.

Page 99: DCSLLL

4 Interpretación MS-DOS Loader

98

Elementos en paralelo - Contacto normalmente abierto (opcode hC8) Se va a comenzar el estudio de la formación de ramas paralelo, con la instrucción

“contacto normalmente abierto”.

Los siguientes ejemplos contemplan todas las posibilidades de ramas paralelo, para deducir la forma en que son codificados.

Caso 1 1001 1002 1003 1004 1005 1006 1007 1008 1009 4001 ├──] [─────] [──┬──] [─────] [─────] [─────] [─────] [─────] [─────] [─────( )── │ │ │ │ │ 2001 2002 │ ├──] [─────] [──┴ 0A000080001000080D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C0D C903E9 C803EA C907D1 C807D2 C37FFF C803EB C803EC C803ED C803EE C803EF C803F0 C803F1 C40FA1 5300000000000000000000

Caso 2 1001 1002 1003 1004 1005 1006 1007 1008 1009 4001 ├──] [─────] [──┬──] [─────] [─────] [─────] [─────] [─────] [─────] [─────( )── │ │ │ │ │ 2001 2002 │ ├──] [──┬──] [──┴ │ │ │ │ │ 3001 │ ├──] [──┴ 0A000080001000080F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C0F C903E9 C803EA CA07D1 C90BB9 C37FFF C807D2 C37FFF C803EB C803EC C803ED C803EE C803EF C803F0 C803F1 C40FA1 5300000000

Codificación

Identificando los elementos con los códigos, se deduce lo siguiente:

• PUNTO 1 (Ramificación pendiente): El opcode hC8 cambia a hC9 cuando antes del elemento a codificar existe una línea de interconexión con la línea inferior. Se continúa codificando los elementos de la línea actual.

• PUNTO 2 (Cambio a línea inferior): El opcode hC8 cambia a hC9 cuando existe una ramificación pendiente y aparece una nueva ramificación en la línea. Se empiezan a codificar los elementos de la línea inferior.

• PUNTO 3 (Cambio a línea inferior y ramificación pendiente): El opcode hC8 cambia a hCA cuando existe una ramificación pendiente, aparece una nueva ramificación en la línea y antes del elemento a codificar existe una línea de interconexión con la línea inferior. Se empiezan a codificar los elementos de la línea inferior.

• PUNTO 4 (Regreso a línea superior): Se utiliza el elemento hC37FFF cuando existe una línea de interconexión con la línea superior. Se continúan codificando los elementos de la línea superior.

Casos adicionales

PUNTO 1

PUNTO 2

PUNTO 4

PUNTO 3

Page 100: DCSLLL

4 Interpretación MS-DOS Loader

99

En los siguientes ejemplos se puede comprobar que con los cuatro puntos anteriores se puede codificar cualquier interconexión. 1001 1002 1003 1004 1005 4001 ├──] [─────] [──┬──] [─────] [──┬──] [─────────────────────────────────────( )── │ │ │ │ │ │ │ 2001 2002 │ 2003 2004 │ ├──] [──┬──] [──┼──] [──┬──] [──┴ │ │ │ │ │ │ │ │ │ 3001 │ │ 3002 │ ├──] [──┴ ├──] [──┴ 0A000080001000081000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C10 C903E9 C803EA CA07D1 C90BB9 C37FFF C807D2 C37FFF C903EB C803EC CA07D3 C90BBA C37FFF C807D4 C37FFF C803ED C40FA1 5300 1001 1002 1003 1004 4001 ───] [──┬──] [─────] [──┬──] [─────────────────────────────────────────────( )── │ │ │ │ │ 2001 2002 │ ├──] [──┬──] [──┼ │ │ │ │ │ 3001 │ ├──] [──┴ 0A000080001000080A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C0A C803E9 C903EA C803EB C907D1 C907D2 C90BB9 C37FFF C37FFF C803EC C40FA1 53000000 1001 1001 1002 1002 4001 ├──] [─────] [─────] [──┬──] [─────────────────────────────────────────────( )── │ │ │ │ │ 2001 │ ├──] [──────────────────┴ 05000080001000080700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C07 C903E9 C803E9 C803EA C907D1 C37FFF C803EA C40FA1 4E 1001 1001 1002 1002 4001 ───] [──┬──] [─────] [─────] [──┬──────────────────────────────────────────( )── │ │ │ │ │ 2001 │ ├──] [──┬───────────────┴ │ │ │ │ │ 3001 │ ├──] [──┴ 05000080001000080900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09 C803E9 C903E9 C803EA C803EA CA07D1 C90BB9 C37FFF C37FFF C40FA1 4E

Elementos en paralelo - Contacto normalmente cerrado (opcode hCC)

Una vez estudiado cómo se interconecta el elemento “contacto normalmente abierto”, se van a aplicar las conclusiones al resto de instrucciones comenzando por “contacto normalmente cerrado”.

Page 101: DCSLLL

4 Interpretación MS-DOS Loader

100

1001 1002 1003 4001 ├──]/[─────]/[──┬──]/[─────────────────────────────────────────────────────( )── │ │ │ │ │ 2001 2002 │ ├──]/[──┬──]/[──┴ │ │ │ │ │ 3001 │ ├──]/[──┴ 0A000080001000080900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C09 CD03E9 CC03EA CE07D1 CD0BB9 C37FFF CC07D2 C37FFF CC03EB C40FA1 53000000000000

Codificación

La codificación es igual que en el caso ya estudiado de contacto normalmente abierto, cambiando los opcodes utilizados.

• PUNTO 1 (Ramificación pendiente): El opcode hCC cambia a hCD.

• PUNTO 2 (Cambio a línea inferior): El opcode hCC cambia a hCD.

• PUNTO 3 (Cambio a línea inferior y ramificación pendiente): El opcode hCC cambia a hCE.

• PUNTO 4 (Regreso a línea superior): Se utiliza el elemento hC37FFF.

Elementos en paralelo – Resto de instrucciones De las pruebas realizadas se concluye que el resto de elementos se comportan de la

forma descrita a continuación. 1001 1002 1003 4001 ├─]/\[────]/\[──┬─]/\[─────────────────────────────────────────────────────( )── │ │ │ │ │ 2001 2002 │ ├─]/\[──┬─]/\[──┴ │ │ │ │ │ 3001 │ ├─]/\[──┴ 0A000080001000080C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C0C C17FFF 4303E9 4303EA C27FFF 4307D1 C17FFF 430BB9 C37FFF 4307D2 C37FFF 4303EB C40FA1 5300000000000000000000000000

Codificación

Las instrucciones “contacto normalmente abierto” y “contacto normalmente cerrado” son un caso excepcional al cambiar el opcode para codificar la interconexión, pues, tal y como se puede comprobar en el este ejemplo con la instrucción “contacto transicional a ON” (opcode h43) el resto de instrucciones añaden un nuevo elemento para cada uno de los casos.

• PUNTO 1 (Ramificación pendiente): Elemento hC17FFF + elemento propio.

• PUNTO 2 (Cambio a línea inferior): hC17FFF + elemento propio.

• PUNTO 3 (Cambio a línea inferior y ramificación pendiente): Elemento hC27FFF + elemento propio.

• PUNTO 4 (Regreso a línea superior): Se utiliza el elemento hC37FFF.

Page 102: DCSLLL

4 Interpretación MS-DOS Loader

101

4.2.3.19. Códigos de control Además de los códigos que corresponden a cada una de las instrucciones que pertenecen

al set de instrucciones, son necesarios los siguientes códigos de control:

Comienzo de bloque de código En el apartado 4.2.3.1 Bloques de programa, se comentaba que el programa se compone

de líneas, que a su vez se componen de elementos. Se decía que estos elementos se agrupan de 82 en 82 elementos, comenzando cada grupo con el código h4C y 1 Byte con el número de elementos del grupo.

Codificación 1 Byte Código (h4C).

1 Byte Número de elementos del bloque en hexadecimal.

Fin de programa corto – 4E Los modelos de LM que después del código de programa no añaden una serie de

códigos llamado en el capítulo 4.2.1 Estructura básica del fichero *.ldr cola, se diferencian de los otros en el código que indica final de la parte de programa.

Codificación

1 Byte Código (h4E).

Tiene el mismo código que el temporizador retentivo de base de tiempos 1 segundo, así que se necesitará controlar el número de elementos pendientes del programa para diferenciar entre uno y otro. Cuando no queden elementos de programa, código de fin.

Fin de programa largo – 53 Los modelos de LM que después del código de programa añaden una serie de códigos

llamado en el capítulo 4.2.1 Estructura básica del fichero *.ldr cola, se diferencian de los otros en el código que indica final de la parte de programa.

Codificación

1 Byte Código (h53).

Marcador/comentario de línea 1001 2001 ───] [─────────────────────────────────────────────────────────────────────( )── L# 2 <1 > 05000080001000080300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C03 C00001 C803E9 C407D1 4E

EL MS-DOS Loader permite asignar un comentario a cada una de las líneas. Para identificarlo, el programa añade un elemento al comienzo de los elementos que corresponden a esa línea.

Codificación

1 Byte Opcode (hC0).

2 Bytes Número del comentario en hexadecimal (MSB LSB).

Page 103: DCSLLL

4 Interpretación MS-DOS Loader

102

4.2.3.20. Tabla resumen

INSTRUCCIÓN SIMBOLO620-06620-15 620-10

620-11620-12620-14

620-1631620-1633

620-36620-25620-35 CODIGO DIRECCION

Instrucciones de contactos y bobinasContacto normalmente abierto -] [- X X X X C8 MSB/LSBContacto normalmente abierto - bifurcación anterior en T X X X X C9 MSB/LSBContacto normalmente abierto - bifurcación anterior en X X X X X CA MSB/LSBContacto normalmente cerrado -]/[- X X X X CC MSB/LSBContacto normalmente cerrado - bifurcación anterior en T X X X X CD MSB/LSBContacto normalmente cerrado - bifurcación anterior en X X X X X CE MSB/LSBContacto transicional a ON -]/\]- X X X X 43 MSB/LSBContacto transicional a OFF -]\/[- X X X X 4B MSB/LSBSalida no retentiva -( )- X X X X C4 MSB/LSBSalida retentiva -(R)- X X X X C5 MSB/LSBsalida latch -(L)- X X X X C6 MSB/LSBSalida unlatch -(U)- X X X X C7 MSB/LSBInstrucciones de bit simpleLectura de bit -]BR[- X 03 EspecialEscribir bit -(BW)- X 85 EspecialRamas serie y paraleloBifurcación descendente en T X X X X C1 7F/FFBifurcación descendente en X X X X X C2 7F/FFBifurcación ascendente en T X X X X C3 7F/FFInstrucciones de temporizadores y contadoresTemporizador retardo a ON 1 segundo -(TON)- X X X X 4A EspecialTemporizador retardo a ON 0.1 segundos -(TON)- X X X X 49 EspecialTemporizador retardo a ON 0.01 segundos -(TON)- X X 68 EspecialTemporizador retardo a OFF 1 segundo -(TOFF)- X X X X 42 EspecialTemporizador retardo a OFF 0.1 segundos -(TOFF)- X X X X 41 EspecialTemporizador retardo a OFF 0.01 segundos -(TOFF)- X X 60 EspecialTemporizador retentivo 1 segundo -(TON)- X X X X 4E EspecialTemporizador retentivo 0.1 segundos -(TON)- X X X X 4D EspecialTemporizador retentivo 0.01 segundos -(TON)- X 6C EspecialContador CTU/CTD X X X X 4F EspecialParametros contador/temporizador X X X X 52 Especial

Tabla 15. Resumen codificación set instrucciones LM (1/4)

Page 104: DCSLLL

4 Interpretación MS-DOS Loader

103

INSTRUCCIÓN SIMBOLO620-06620-15 620-10

620-11620-12620-14

620-1631620-1633

620-36620-25620-35 CODIGO DIRECCION

Instrucciones de saltoNo salto con retención NSKR X X X X 46 MSB/LSBNo salto con desactivación NSKD X X X X 47 MSB/LSBFin de salto EOS X X X X 34 MSB/LSBInstrucciones de manipulación de datosLectura de datos (Bring in) -[B2]- X X X 88 MSB/LSBLectura de datos indirecta -<B2>- X X X 89 MSB/LSBLectura de datos en coma flotante -[FP]- X A8 MSB/LSBEscritura de datos -(S2)- X X X 07 MSB/LSBEscritura de datos indirecta -(I2)- X X X 06 MSB/LSBEscritura de datos en coma flotante -(FP)- X 27 MSB/LSBConstante -[K2]- X X X 8B MSB/LSBConstante en coma flotante (primera palabra) -[FPK]- X 9B LSB/LLSBConstante en coma flotante (segunda palabra) -[FPK]- X AB MMSB/MSBLectura de datos 1-8 bloques de 16 bits zona I/O (PULL) -[PUL]- X X X 80 EspecialLectura de datos 1-8 bloques de 16 bits zona Reg. (PULL) -[PUL]- X X X 82 EspecialEscritura de datos 1-8 bloques de 16 bits zona I/O (PUSH) -(PSH)- X X X 84 EspecialEscritura de datos 1-8 bloques de 16 bits zona Reg. (PUSH) -(PSH)- X X X 86 EspecialLectura de datos tabla estados del sistema (PULS) -[PULS]- X 81 EspecialInstrucciones de comparación de enterosIgual que -]=[- X X X 08 7F/FFMenor que -]<[- X X X 09 7F/FFMayor que -]>[- X X X 0A 7F/FFPrueba de cero -]Z[- X X X 8D MSB/LSBInstrucciones matemáticasSuma -[+]- X X X 0E 7F/FFSuma con dirección de error -[+]- X X X 0E MSB/LSBResta -[-]- X X X 0D 7F/FFResta con dirección de error -[-]- X X X 0D MSB/LSBMultiplicación -[*]- X X X 0C 7F/FFMultiplicación con dirección de error -[*]- X X X 0C MSB/LSBDivisión -[/]- X X X 0B 7F/FFDivisión con dirección de error -[/]- X X X 0B MSB/LSB

Tabla 16. Resumen codificación set instrucciones LM (2/4)

Page 105: DCSLLL

4 Interpretación MS-DOS Loader

104

INSTRUCCIÓN SIMBOLO620-06620-15 620-10

620-11620-12620-14

620-1631620-1633

620-36620-25620-35 CODIGO DIRECCION

Instrucciones de operadores lógicosAND bloque de 16 bits -[&]- X 2C 7F/FFOR bloque de 16 bits -[OR]- X 2E 7F/FFXOR bloque de 16 bits -[XOR]- X 3E 7F/FFInstrucciones de referencia de memoriaNo salto con retención (8192-8447) NSKR X X X X 46 MSB/LSBNo salto con retención (8448) NSKR X X X 46 MSB/LSBSalto a subrutina JSR X X 04 EspecialSubrutina SUB X X 24 EspecialRetorno a subrutina RTS X X 14 EspecialRetorno a principio de programa RBP X X X X 05 7F/FFInstrucciones de conversión de datosConversión binario a BCD -[BCD]- X 1F 7F/FFConversión binario a BCD con dirección de error -[BCD]- X 1F MSB/LSBConversión BCD a binario -[BIN]- X 0F 7F/FFConversión BCD a binario con dirección de error -[BIN]- X 0F MSB/LSBConversión entero a coma flotante -[FLT]- X 2F 7F/FFConversión entero a coma flotante con dirección de error -[FLT]- X 2F MSB/LSBConversión coma flotante a entero -[INT]- X 3F 7F/FFConversión coma flotante a entero con dirección de error -[INT]- X 3F MSB/LSBValor absoluto -[ABS]- X 1C 7F/FFValor absoluto con dirección de error -[ABS]- X 1C MSB/LSBRaiz cuadrada -[SQRT]- X 2D 7F/FFRaiz cuadrada con dirección de error -[SQRT]- X 2D MSB/LSBComplemento a dos bloque de 16 bits (Negacion) -[NEG]- X 1E 7F/FFInversión de bits bloque de 16 bits (Not) -[NOT]- X 1D 7F/FFInstrucciones de secuenciadorSecuenciador X X X X 8A EspecialCarga secuenciador -(LS2)- X X X 44 MSB/LSBDescarga secuenciador -(US2)- X X 45 MSB/LSB

Tabla 17. Resumen codificación set instrucciones LM (3/4)

Page 106: DCSLLL

4 Interpretación MS-DOS Loader

105

INSTRUCCIÓN SIMBOLO620-06620-15 620-10

620-11620-12620-14

620-1631620-1633

620-36620-25620-35 CODIGO DIRECCION

Instrucciones de matricesMatriz de puesta a cero y de puesta a uno X X AE 00/0A+EspMover matriz X X AE 00/00+EspInvertir matriz X X AE 00/02+EspMatriz OR X X AE 00/04+EspMatriz OR exclusiva X X AE 00/08+EspMatriz AND X X AE 00/06+EspComparar matriz X X AE 00/0C+EspInstrucciones diversasRetardo (DLA) -[DLA]- X CF MSB/LSBOperación nula NOP X X X X FF 7F/FEOperación nula NOP 00 MSB/LSBExploración estado entradas ISS X X X X 8F 7F/FFInstrucciones no descritas en el manualInversor lógico -]o[- X CB 7F/FFCodigos de controlComienzo de bloque de código 4C LSBFin de programa (corto) 4E -Fin de programa (largo) 53 -Marcador/comentario de línea C0 MSB/LSB

Tabla 18. Resumen codificación set instrucciones LM (4/4)

Page 107: DCSLLL

4 Interpretación MS-DOS Loader

106

4.2.4. Cola Se aprecia visualmente que existen modelos de procesador con ficheros *.ldr más largos

que otros. Tal y como se ha comentado en el capítulo anterior, existen modelos que después del código de fin de programa (h4E o h53) todavía contienen más códigos. Al no ocupar esta parte registros en la memoria de programa, ya que el número de registros libres se reduce en la misma cantidad en modelos con cola que sin cola, no nos interesa para realizar la simulación.

En la última columna se indica con “Corto” los modelos que no tienen cola (código de fin de programa h4E) y con “Largo” los modelos que tienen cola (código de fin de programa h53).

Modelo Código Hexa Código Decimal Tipo 620-06 h01 1 Corto 620-10O h00 0 Corto 620-10N h00 0 Corto 620-11 h06 6 Largo 620-12 h0B 11 Largo 620-14 h07 7 Largo 620-15O h01 1 Corto 620-15N h01 1 Corto 620-16 h08 8 Largo 620-20 h02 2 Corto 620-25 h04 4 Corto 620-30 h03 3 Corto 620-35 h05 5 Corto 620-36 h0A 10 Largo

Tabla 19. Cola

Page 108: DCSLLL

4 Interpretación MS-DOS Loader

107

4.3. F3 – Documentation functions Se utiliza para acceder a la zona de edición de las funciones de documentación.

Figura 36. MS-DOS Loader – F3 Pantalla edición Documentation functions

En la captura se aprecia el menú de selección con las siguientes funciones de documentación:

• “F1 - Function block name parameter editor”: Editor de nombres de parámetros de bloques de función.

• “F2 - Address label editor”: Editor etiquetas de dirección.

• “F3 - Address comment editor”: Editor comentarios de dirección.

• “F4 - line comment editor”: Editor comentarios de líneas.

• “F5 - skip label editor”: Editor etiquetas de saltos.

• “F6 - subroutine label editor”: Editor etiquetas de subrutinas.

• “F7 - bit comment editor“: Editor comentarios de bit.

• “F8 - bit label editor“: Editor etiquetas de bit.

Cada una de estas funciones de documentación utiliza un archivo distinto para guardar los datos:

• F1 - Function block name parameter editor *.fbl

• F2 - Address label editor *.lbl

• F3 - Address comment editor *.ace

• F4 - Line comment editor *.lce

• F5 - Skip label editor *.skp

• F6 - Subroutine label editor *.jsr

• F7 - Bit comment editor *.bce

• F8 - Bit label editor *.blb

Page 109: DCSLLL

4 Interpretación MS-DOS Loader

108

De los listados superiores y de las ventanas que aparecen al seleccionar cada una de las opciones, se deduce que estas funciones de documentación se pueden agrupar en tres tipos principales: Nombre de parámetros (“Name parameter”), Etiquetas (“Label”) y Comentarios (“Comment”).

4.3.1. Nombre de parámetros

Figura 37. MS-DOS Loader – F3 F1 FB Name parameter editor

No funciona correctamente. Cuando se intenta cargar uno de los bloques grabados con anterioridad da un aviso de tamaño incorrecto y aborta la carga.

Como no se sabe como debe de funcionar, se decide no estudiar de esta parte.

4.3.2. Etiquetas Sirven para describir el servicio del elemento en cuestión, ya sea de una dirección, de un

bit, de un salto o de una subrutina.

Tal y como se aprecia en la captura siguiente, cada etiqueta se compone de cuatro campos:

• “Label” Etiqueta: Siete caracteres para el nombre.

• “Description #1” Descripción número 1: Nueve caracteres para la descripción.

• “Description #2” Descripción número 2: Nueve caracteres para la descripción.

• “Description #3” Descripción número 3: Nueve caracteres para la descripción.

Page 110: DCSLLL

4 Interpretación MS-DOS Loader

109

Figura 38. MS-DOS Loader – F3 F2 Address label editor

4.3.2.1. Codificación y estructura básica de los archivos Los ficheros que contienen cada uno de los cuatro tipos de etiquetas son: *.lbl (etiquetas

de dirección), *.blb (etiquetas de bit), *.skp (etiquetas de salto), *.jsr (etiquetas de subrutina).

Una vez estudiados estos ficheros de documentación de etiquetas, se deduce que corresponden a un fichero mezcla de códigos ASCII y hexadecimal, así, los campos de texto que forman la etiqueta (nombre y descripción) se guardan como ASCII, mientras que la información adicional como por ejemplo el número de etiqueta se guarda en hexadecimal.

Cada etiqueta ocupa un bloque de 36 Bytes.

Pos. Descripción Nº Bytes Formato 1 Número de etiqueta 2 Hexa (LSB MSB) 2 Campo nombre 7 ASCII 3 Campo #1 descripción 9 ASCII 4 Campo #2 descripción 9 ASCII 5 Campo #3 descripción 9 ASCII 6 Se repiten pos. 1, 2, 3, 4 y 5 hasta alcanzar número de etiquetas totales del fichero.

Tabla 20. Estructura de los archivos de etiquetas (*.lbl ,*.blb, *.skp, *.jsr)

Por defecto, se guardan en orden numérico ascendente, aunque si se modifican externamente de forma desordenada el MS-DOS Loader sigue funcionando correctamente.

No se ocupan con reservas las direcciones intermedias no utilizadas.

4.3.2.2. Particularidades Las particularidades residen en que rango puede tomar el campo número de etiqueta en

función de si se trabaja con direcciones, bits, saltos o subrutinas.

Page 111: DCSLLL

4 Interpretación MS-DOS Loader

110

Etiquetas de dirección No se adapta al mapeado de memoria del LM elegido, trabajando siempre con el

máximo rango posible.

Rango de 0 a 8191.

Etiquetas de bit No se adapta al mapeado de memoria del LM elegido, trabajando siempre con el

máximo rango posible de la zona de registros, 4096 a 8191.

Al bit 0 de la dirección (2 Bytes) 4096 le corresponde el número de etiqueta 0, mientras que al bit 0 de la palabra 4097 le corresponde el número 16. Así al bit 15 de la dirección 8191 le corresponde el número 65535.

Rango de 0 a 65535.

Etiquetas de salto Rango de 0 a 32767.

Etiquetas de subrutina Rango de 0 a 255.

4.3.3. Comentarios Permiten realizar un comentario del elemento en cuestión, ya sea de una dirección, de

un bit o de una línea.

Tal y como se aprecia en la captura siguiente, cada comentario se compone de un único campo de 1340 caracteres, distribuidos en 20 líneas de 67 caracteres cada una.

Figura 39. MS-DOS Loader – F3 F4 Line comment editor

4.3.3.1. Codificación y estructura de los ficheros Los ficheros que contienen cada uno de los tres tipos de comentarios son: *.ace

(comentarios de dirección), *.lce (comentarios de línea), *.bce (comentarios de bit).

Una vez estudiados los ficheros de documentación de comentarios, se deduce que al igual que los ficheros de etiquetas, utilizan mezcla entre código ASCII y hexadecimal.

Page 112: DCSLLL

4 Interpretación MS-DOS Loader

111

Cada comentario ocupa un bloque de dimensión variable.

Pos. Descripción Nº Bytes Formato

Cabecera 1 Número total de comentarios 2 Hexa (LSB MSB)

Cuerpo 2 Número de comentario 2 Hexa (LSB MSB) 3 Número de líneas

(Máximo de 20) 2 Hexa (LSB MSB)

4 Texto de las líneas1 67 x NLíneas (pos. 3) ASCII 5 Se repiten pos. 2, 3 y 4 hasta alcanzar número de comentarios totales del fichero

(pos. 1).

Tabla 21. Estructura de los ficheros de comentarios (*.ace ,*.lce, *.bce)

4.3.3.2. Particularidades Las particularidades residen en que rango puede tomar el campo número de comentario

en función de si se trabaja con direcciones, líneas o bits.

Comentarios de dirección No se adapta al mapeado de memoria del LM elegido, trabajando siempre con el

máximo rango posible.

Rango de 0 a 8191.

Comentarios de línea A cada línea se le asigna el número de comentario que se quiera, pudiendo repetir el

comentario en tantas líneas se quiera.

Funciona de igual forma que comentario de direcciones, pero indicando el número del comentario y no el número de dirección.

Rango de 0 a 32767.

Comentarios de bit

No se adapta al mapeado de memoria del LM elegido, trabajando siempre con el máximo rango posible de la zona de registros, 4096 a 8191.

Al bit 0 de la dirección (2 Bytes) 4096 le corresponde el número de etiqueta 0, mientras que al bit 0 de la palabra 4097 le corresponde el número 16. Así al bit 15 de la dirección 8191 le corresponde el número 65535.

Rango de 0 a 65535.

4.4. F4 - Password and security functions

Permite configurar passwords para evitar que usuarios no permitidos accedan a los funciones de edición de programa y configuración del MS-DOS Loader.

Al no ser de nuestro interés no se estudia esta opción.

1 Aunque sólo se utilice el carácter de una línea se almacena entera rellenando con

blancos (código ASCII en hexadecimal 20).

Page 113: DCSLLL

4 Interpretación MS-DOS Loader

112

4.5. F5 - I/O configuration utilities Informa de que no se han encontrado y aborta el proceso.

No se ha encontrado ninguna descripción de esta función ni en manuales ni en la ayuda rápida del MS-DOS Loader, por lo que no se estudia esta opción.

4.6. F6 - 623 Software configuration *.cfg Se utiliza para acceder a la zona de edición de parámetros de configuración que

permiten al usuario entre otras cosas determinar la configuración física del sistema, rutas de ficheros y formas de visualizar y editar el programa.

Figura 40. MS-DOS Loader – F6 Pantalla edición 623-60 Software Configuration

Se observa como estos parámetros están agrupados en 5 categorías.

• Paths and files

• Operational mode

• System type and file loads

• Stand-alone parameters

• Multidrop node names

Las siguientes capturas muestran el menú de cada una de esas categorías.

Page 114: DCSLLL

4 Interpretación MS-DOS Loader

113

Figura 41. MS-DOS Loader – F6 F1 Paths and Files

Figura 42. MS-DOS Loader - F6 F2 Operational Modes

Page 115: DCSLLL

4 Interpretación MS-DOS Loader

114

Figura 43. MS-DOS Loader - F6 F3 System type and file loads

Figura 44. MS-DOS Loader - F6 F4 Stand-Alone parameters

Page 116: DCSLLL

4 Interpretación MS-DOS Loader

115

Figura 45. MS-DOS Loader - F6 F5 Multidrop node names

Toda esta información se codifica en el fichero con extensión *.cfg, de la forma en que se describe en el apartado siguiente.

4.6.1. Codificación y estructura del fichero *.cfg El fichero *.cfg, es un fichero de texto en formato ASCII donde cada línea representa a

uno de los parámetros de configuración.

Para poder identificar quien es quien, se ha cambiado cada parámetro y luego se ha comprobado que línea había reflejado el cambio. También se ha anotado que código le corresponde a cada uno de los valores que puede tomar el parámetro.

La siguiente tabla es el resumen de dichas pruebas.

La primera columna es el número de línea.

La segunda columna es el contenido de la línea en el fichero *.cfg ejemplo. Los datos corresponden al fichero de configuración del proyecto visualizado en las capturas de pantalla.

La tercera columna indica el grupo y el nombre del parámetro que representa, así como el rango de valores que puede tener en función de las opciones que se pueden seleccionar en cada parámetro. En los casos en que se codifica un parámetro con sólo dos valores posibles, se utiliza el símbolo # para identificar la opción que es codificada con un cero.

NLinea CONTENIDO PARÁMETRO 1 CFG04 ?? 2 d:\proyecto\623-

60\OPSM\LM15\ PF1 Ladder Path

3 OPSMLM15 PF Ladder File 4 d:\proyecto\623-

60\OPSM\LM15\ PF Label Path (*.lbl/blb/jsr/skp/ace/bce/lce)

5 OPSMLM15 PF Label File Tabla 22. Estructura del archivo *.cfg (1/2)

1 Abreviatura de “Paths and files”

Page 117: DCSLLL

4 Interpretación MS-DOS Loader

116

NLinea CONTENIDO PARÁMETRO 6 PF Temp Path 7 200 PF Label Cache Size 10 ≤ X ≤ 200 8 10000 PF Maximun Labels 1000 ≤ X ≤ 16640 9 4000 PF Maximun Comments 1000 ≤ X ≤ 24576 10 620 PF 620 Driver File 11 0 PF Driver Node 0 ≤ X ≤ 31 12 1 OM1 Auto clear #OFF/ON 13 1 OM Scan time display #OFF/ON 14 1 OM duplicate output check #OFF/ON 15 1 OM Full time detail #OFF/ON 16 1 OM Beep #OFF/ON 17 1 OM Float width #SINGLE/DOUBLE 18 0 OM Float display mode #(DEC/EXP)/EXP 19 3 OM Number of Decimal Digits 0÷6 20 0 OM Printer characters #STANDARD/GRAPHICS 21 1 ST2 Display type #MONO/COLOR 22 0 ST Communication port 0÷2

(BOARD/COM1/COM2) 23 4 ST Interrupt request level 2÷7 24 1661 ?? 25 13 SA3 Model number

0(620-06) 1(20-10O) 2(620-10N) 3(620-11) 4(620-12) 5(620-14) 6(620-15O) 7(620-15N) 8(620-16) 9(620-20) 10(620-25) 12(620-30) 13(620-35) 14(620-36)

26 841 ST Current Ladder Line 27 0 ST Ladder logic load 0÷2 (PROMPT/LOAD/NO

LOAD) 28 0 ST Documentation load 0÷2 (PROMPT/LOAD/NO

LOAD) 29 1 ST Edit path and files #OFF/ON 30 0 OM Logic group hold #OFF/ON 31 32768 SA Memory size 32 4096 SA Register size 33 2048 SA Real I/O size 34 MD4 Node name #1 35 MD Node name #2 … … 66 MD Node name #32

Tabla 23. Estructura del archivo *.cfg (2/2)

1 Abreviatura de “Operational mode” 2 Abreviatura de “System type and file loads” 3 Abreviatura de “Stand-alone parameters” 4 Abreviatura de “Multidrop node names”

Page 118: DCSLLL

4 Interpretación MS-DOS Loader

117

Los parámetros codificados en las líneas 25 (Numero modelo LM), 31 (Tamaño de memoria de programa), 32 (Tamaño de registros) y 33 (Tamaño real E/S), configuran el mapeado de memoria del Logic Manager. Los diversos mapeados de memoria se estudian en el capítulo 4.6.2.

Se observa que el número que codifica el modelo de procesador de LM según el fichero *.cfg, no coincide con el código que contiene el fichero *.ldr. La siguiente tabla contrasta estas diferencias.

Modelo procesador LM *.cfg *.ldr 620-06 0 1 620-10O 1 0 620-10N 2 0 620-11 3 6 620-12 4 11 620-14 5 7 620-15O 6 1 620-15N 7 1 620-16 8 8 620-20 9 2 620-25 10 4 620-30 12 3 620-35 13 5 620-36 14 10

Tabla 24. Código de modelo de procesador según fichero *.cfg o *.cfg.

Page 119: DCSLLL

4 Interpretación MS-DOS Loader

118

4.6.2. Mapeado de memoria La siguiente figura caracteriza las distintas zonas en que se divide el mapa de memoria

del Logic Manager.

Figura 46. Mapeado de memoria

Memoria de programa

24 bits E/S reales

1 bit

Memoria de usuario

Memoria de sistema

Memoria RAM 8 bit

Bobinas internas

1 bit

Registros internos 16 bits

o 16+1 bits

Estado Sistema

8 bit

En caso de módulo E/S analógico, registro de16 bits. Según modelo se pueden utilizar las posiciones libres de E/S realescomo bobinas internas

0 - 0 - 0 -

32767 -

2047/8N/N+1 -

4096 -

8191 -

4095M -

Page 120: DCSLLL

4 Interpretación MS-DOS Loader

119

4.6.2.1. Según el MS-DOS Loader Según los datos extraídos del programa MS-Dos Loader en función del modelo de procesador, los parámetros en cuestión pueden tener los

valores siguientes:

Modelo Memoria de programa (31) Registros (32) E/S reales (33) 620-06 2048 256 192 620-10O 2048,1024,512 256 256 620-10N 4096,2048,1024*1,512* 512,256* 512,256* 620-11 8192 4096 256 620-12 2048 256 256 620-14 8192 4096 640 620-15O 2048,1024,512 256 256 620-15N 4096,2048,1024*,512* 512,256* 512,256* 620-16 8192 4096 2048,1024 620-20 8192,4096,2048 2048 512 620-25 32768 - 2048 4096,2048 2048,1024,512 620-30 24576,20480,18432,16384,12288,10240,8192,4096,2048 4096,2048 2048 620-35 32768 - 2048 4096,2048 2048,1024,512 620-36 32768 4096 2048

Tabla 25. Mapeado de memoria según MS-DOS Loader.

Todavía falta saber las direcciones de comienzo y final de cada una de las zonas. Para ello, consultando el documento “623 MS-Dos Loader, Guía de programación”, obtenemos los rangos de direcciones siguientes.

1 Para los valores de memoria de programa marcados con *, le corresponden los valores de registros y E/S reales marcados de igual forma.

Page 121: DCSLLL

4 Interpretación MS-DOS Loader

120

4.6.2.2. Según el manual de programación De acuerdo a la documentación en función del modelo de procesador, el mapeado de memoria es el siguiente:

Modelo Memoria de

programa 24 bits E/S reales 1 bit

Bobinas internas 1 bit

Registros internos 16 bits

Tamaño Tamaño Rango Tamaño Rango Tamaño Rango 620-06 2048 192 0-191 576 191-767 256 4096-4351 620-10O - - - - - - - 620-10N 1024,512 256 0-255 512 256-767 256 4096-4351 620-10N 4096,2048 512 0-511 512 512-1023 512 4096-4607 620-11 8192 256 0-255 3840 256-4095 4096 4096-8191 620-12 2048 256 0-255 3840 256-4095 256 4096-4351 620-14 8192 640 0-639 3456 640-4095 4096 4096-8191 620-15O - - - - - - - 620-15N 1024,512 256 0-255 512 256-767 256 4096-4351 620-15N 4096,2048 512 0-511 512 512-1023 512 4096-4607 620-16 8192 2040 0-2039 (3) 2048 2048-4095 4096 4096-8191 620-20 620-25 (2k) - 2048 0-2039 (3) 2048 0-2047 (4) 2048 4096-6143 (1) (2) 620-25 (4k) - 2048 0-2039 (3) 4096 0-4095 (4) 4096 4096-8191 (1) (2) 620-30 620-35 (2k) - 2048 0-2039 (3) 2048 0-2047 (4) 2048 4096-6143 (1) (2) 620-35 (4k) - 2048 0-2039 (3) 4096 0-4095 (4) 4096 4096-8191 (1) (2) 620-36 32768 2048 0-2039 (3) 4096 2048-4095 4096 4096-8191

Tabla 26. Mapeado de memoria según manual de programación.

Nota 1.- El intervalo 4096-4111 es donde se deben de albergar los temporizadores con base 0,01 segundos (modelos 620-25/35). Nota 2.- Zona 16+1 bits. Pueden trabajar con operadores de 1 bit en la zona de registros debido a que usan el bit de signo. Nota 3.- Las direcciones 2040-2047 se reservan para la comunicación serie. Nota 4.- Soportan mezclar bobinas internas en el área de E/S, utilizando aquellas direcciones que no están siendo utilizadas.

Page 122: DCSLLL

4 Interpretación MS-DOS Loader

121

4.6.2.3. Resumen Reuniendo ambas tablas para completar una, obtenemos:

Modelo Memoria de

programa 24 bits E/S reales 1 bit

Bobinas internas 1 bit

Registros internos 16 bits

Tamaño Tamaño Rango Tamaño Rango Tamaño Rango 620-06 2048 192 0-191 576 191-767 256 4096-4351 620-10O - 256 0-255 512 256-767 256 4096-4351 620-10N 1024,512 256 0-255 512 256-767 256 4096-4351 620-10N 4096,2048 512 0-511 512 512-1023 512 4096-4607 620-11 8192 256 0-255 3840 256-4095 4096 4096-8191 620-12 2048 256 0-255 3840 256-4095 256 4096-4351 620-14 8192 640 0-639 3456 640-4095 4096 4096-8191 620-15O - 256 0-255 512 256-767 256 4096-4351 620-15N 1024,512 256 0-255 512 256-767 256 4096-4351 620-15N 4096,2048 512 0-511 512 512-1023 512 4096-4607 620-16 8192 2040 0-2039 (3) 2048 2048-4095 4096 4096-8191 620-20 512 0-511 2048 0-2047 2048 4096-6143 (2) 620-25 (2k) - 2048 0-2039 (3) 2048 0-2047 (4) 2048 4096-6143 (1) (2) 620-25 (4k) - 2048 0-2039 (3) 4096 0-4095 (4) 4096 4096-8191 (1) (2) 620-30 (2k) - 2048 0-2039 (3) 2048 0-2047 (4) 2048 4096-6143 (2) 620-30 (4k) - 2048 0-2039 (3) 4096 0-4095 (4) 4096 4096-8191 (2) 620-35 (2k) - 2048 0-2039 (3) 2048 0-2047 (4) 2048 4096-6143 (1) (2) 620-35 (4k) - 2048 0-2039 (3) 4096 0-4095 (4) 4096 4096-8191 (1) (2) 620-36 32768 2048 0-2039 (3) 4096 2048-4095 4096 4096-8191

Tabla 27. Mapeado de memoria

Nota 1.- El intervalo 4096-4111 es donde se deben de albergar los temporizadores con base 0,01 segundos (modelos 620-25/35). Nota 2.- Zona 16+1 bits. Pueden trabajar con operadores de 1 bit en la zona de registros debido a que usan el bit de signo. Nota 3.- Las direcciones 2040-2047 se reservan para la comunicación serie. Nota 4.- Soportan mezclar bobinas internas en el área de E/S, utilizando aquellas direcciones que no están siendo utilizadas.

Page 123: DCSLLL

5 Programación

122

5. Programación 5.1. Lenguaje de programación

Como se quiere trabajar con entorno Windows, para la programación del simulador se ha elegido la aplicación Visual Basic.

Para entender la mayoría de las decisiones tomadas en este capítulo, es necesario referirse al capítulo 4 Interpretación MS-DOS Loader.

Los flujogramas que explican como funcionan las rutinas que componen el programa, se han redactado textual y no gráficamente. La siguiente equivalencia entre ambos métodos aclara el concepto:

Acción 1

A=B

Si Acción 2

No Rutina 1

C=D

Si … Repetir cuatro últimos pasos

Fin

A=B

Fin

Acción 2 Rutina 1

C=D

Acción 1

NO

SI

NO

SI

Page 124: DCSLLL

5 Programación

123

5.2. Filosofía de programación Para facilitar la programación, se ha dividido el trabajo en diversos elementos, cada uno

encargado de realizar tareas específicas, que al trabajar conjuntamente conforman el programa de simulación.

Así, se han desarrollado los siguientes módulos:

• Ventana de presentación (Frm_ModalSplash)

• Ventana principal (Frm_MDI)

• Ventana de configuración (Frm_MDIChildConfiguracion)

• Ventana de documentación (Frm_MDIChildDocumentacion)

• Ventana de memoria interna (Frm_MDIChildMemoria)

• Ventana de programa (Frm_MDIChildPrograma)

• Ventana de simulación (Frm_MDIChildSimulacion)

• Ventana de selección de fichero (Frm_ModalSeleccionFicheros)

• Módulo de soporte general (Mdl_General)

• Módulo de soporte proyecto (Mdl_Proyecto)

• Módulo de soporte para separar líneas de *.ldr (Mdl_SepararLineas)

• Módulo de soporte para interpretar las líneas de *.ldr (Mdl_InterpretarLineas)

• Módulo de soporte tablas internas (Mdl_TablasInternas)

• Módulo de soporte para bases de datos (Mdl_BasesdeDatos)

• Módulo de soporte para simular programa (Mdl_Simular)

En los siguientes capítulos se describe que hacen, como lo hacen y por que lo hacen de esta forma.

5.2.1. Descripción básica

Una descripción muy simple de lo que hace cada uno de ellos es la siguiente:

Ventana de presentación – Frm_Splash Aparece unos instantes al comienzo de la ejecución del programa, presentando

información del programa. Mientras, en segundo plano, continúa la carga del programa.

Ventana principal – Frm_MDI Ventana MDI1.

Contiene el menú, la barra de herramientas y la barra de estado. Se encarga por tanto de gestionar las llamadas al resto de elementos.

Ventana de configuración – Frm_MDIChildConfiguracion Ventana MDIchild1.

1 MDI – Término de programación que indica que la ventana aloja y gestiona al resto de

ventanas que cuelgan de ella. (Ejemplo, Microsoft Word)

Page 125: DCSLLL

5 Programación

124

Aparece a solicitud del usuario por medio del menú.

Ventana de edición de los parámetros de configuración del proyecto abierto (archivo *.cfg).

Ventana de documentación – Frm_MDIChildDocumentacion Ventana MDIchild.

Aparece a solicitud del usuario por medio del menú.

Ventana de edición de los archivos de documentación del proyecto abierto.

• *.lbl - Address_label – Etiquetas de direcciones

• *.ace - Address_comment – Comentarios de direcciones

• *.lce - Line_comment - Comentarios de líneas de programa

• *.skp - Skip_label – Etiquetas de líneas de salto

• *.jsr - Subroutine_label – Etiquetas de líneas de subrutina

• *.bce - Bit_Comment – Comentarios de bit

• *.blb - Bit_label – Etiquetas de bit

Ventana de mapeado de memoria– Frm_MDIChildMemoria Ventana MDIchild.

Aparece a solicitud del usuario por medio del menú.

Ventana de edición de las tablas de mapeado de memoria del Logic Manager:

• Memoria de usuario: Tabla de estados E/S (I/O) y tabla de registros.

• Memoria de sistema: Tabla de estados del sistema.

Ventana de programa – Frm_MDIChildPrograma Ventana MDIchild.

Aparece a solicitud del usuario por medio del menú.

Ventana de visualización de las líneas de programa. Si se está depurando un programa, se visualiza el estado o valor de los elementos de la línea lógica a medida que progresa el scan del programa.

Ventana de simulación – Frm_MDIChildSimulacion Ventana MDIchild.

Aparece a solicitud del usuario por medio del menú.

Ventana de edición de los parámetros de configuración de la simulación y de las expresiones que describen la evolución de las direcciones simulando las entradas del sistema.

1 MDIchild – Término de programación que indica que la ventana depende de una

ventana principal, no existiendo fuera de la misma. (Ejemplo, Documento de Microsoft Word)

Page 126: DCSLLL

5 Programación

125

También visualiza los cronogramas con la evolución de las direcciones binarias seleccionadas.

Ventana de selección de fichero – Frm_ModalSeleccionFichero Ventana modal1.

Aparece a solicitud del usuario por medio del menú o automáticamente cuando se cierra el proyecto en curso.

Permite al usuario seleccionar que ficheros del proyecto abierto desea actualizar con los cambios realizados.

Módulo de soporte general – Mdl_General Librería de procedimientos comunes utilizados en el resto de elementos.

Módulo de soporte de las tablas internas – Mdl_TablasInternas Librería de procedimientos para crear, borrar y editar datos de las tablas internas que

implementan las tablas de memoria de usuario, de sistema y de programa, así como la evolución de las direcciones binarias a lo largo de la simulación.

Módulo de soporte de las bases de datos – Mdl_BasesdeDatos Librería de procedimientos para crear, borrar y editar registros de las tablas de la base

de datos con la información de los archivos de documentación y las expresiones de evolución de cada dirección.

Módulo de soporte de archivos del proyecto – Mdl_Proyecto Librería de procedimientos para leer, interpretar y escribir los datos que contienen los

archivos de configuración, de documentación y de programa.

Debido a la complejidad que presenta la decodificación de la parte del archivo de programa (*.ldr) que contiene las líneas del programa, el módulo siguiente contiene los procedimientos encargados de esa tarea.

Módulo de soporte para separar líneas de *.ldr – Mdl_SeparaLineas Librería de procedimientos para interpretar los códigos que contiene la parte del fichero

*.ldr con las líneas logicas, y así poder identificarlas y separarlas a la hora de abrir el proyecto.

Módulo de soporte para interpretar las líneas de *.ldr (Mdl_InterpretarLineas)

Librería de procedimientos encargados de interpretar los elementos de una línea de programa, para permitir su visualización en la ventana de programa.

Módulo de soporte para simular el programa – Mdl_Simular Librería de procedimientos para simular las líneas de programa obteniendo los nuevos

valores de las direcciones de salida, a partir de la combinación de los valores de las direcciones de entrada.

1 Modal – Término de programación que indica que cuando esta ventana esta abierta, se

interrumpe la ejecución del resto de ventanas del programa hasta que no se atienda la solicitud.

Page 127: DCSLLL

5 Programación

126

5.2.2. Interacción de elementos La siguiente figura representa como interactúan los módulos descritos anteriormente.

Tablas internasArchivos del proyecto

MDI(Frm_MDI)

Splash(Frm_Splash)

Configuración(Frm_MDIChildConfiguracion)

Documentación(Frm_MDIChildDocumentacion)

Simulación(Frm_MDIChildSimulacion)

Programa(Frm_MDIChildPrograma)

Mapeado memoria(Frm_MDIChildMemoria)

Ficheros de documentación

*.lblEtiquetas

direcciones

*.blbEtiquetas

bits

*.aceComentariosdirecciones

*.skpEtiquetas

salto

*.bceComentarios

bits

*.jsrEtiquetassubrutina

*.slmParámetrossimulación

*.cfgFichero de

configuración

*.ldrFichero de líneas de

programa

Tablas Internas(Mdl_TablasInternas)

Base de datos

Comentarios dirección(Address comment)

Comentarios línea(Line comment)

Comentarios bit(Bit comment)

Etiquetas direccion(Address label)

Etiquetas bit(Bit label)

Etiquetas subrutina(Subroutine label)

Etiquetas salto(Skip label)

Memoria de usuario(MemU_Usuario)

Configuración progr.(Con_Programa)

Memoria de sistema(MemS_Sistema)

Lineas de programa(Lin_Programa)

Partes de programa(Par_Programa)

*.lceComentarios

líneas

General(Mdl_General)

(Frm_ModalSeleccion-Ficheros)

Simular archivo *.ldr(Mdl_Simular)

Base de datos(Mdl_BasesdeDatos)

Separar líneas archivo*.ldr

(Mdl_SepararLineas)

Archivos del proyecto(Mdl_Proyecto)

Interpretar lineas(Mdl_InterpretarLinea

s)

INICIO(Main)

Figura 47. Interacción de elementos.

Page 128: DCSLLL

5 Programación

127

5.3. ¿Bases de datos o tablas en memoria interna? Antes de empezar a programar, hay que decidir cómo almacenar los datos que se

decodifican de los archivos de configuración, documentación y programa, así como las zonas de memoria de usuario y de sistema.

Existen dos formas principales: usar bases de datos en un archivo externo o usar tablas en memoria interna.

Por un lado, uno de los objetivos del proyecto es facilitar la edición de los datos de documentación por medio de Access, lo que es un gran peso a favor de las bases de datos.

Otro punto a favor de las bases de datos, es que Visual Basic dispone de controles específicamente diseñados para trabajar con las mismas, de forma que se tienen muchas y potentes herramientas ya desarrolladas.

En cambio, el trabajar con tablas de memoria interna implica desarrollar funciones de acceso, edición y visualización de los datos y si se quiere respetar el objetivo de la edición con Access, obliga a implementar una función adicional de exportación e importación de los datos de las tablas en memoria interna.

Finalmente se ha decidido almacenar los distintos tipos de datos de la siguiente forma: • Archivo de configuración: Tablas de memoria. • Archivos de documentación: Base de datos. • Archivo de programa: Tablas de memoria. • Memoria de usuario y de sistema: Tablas de memoria

En los siguientes apartados se explica por qué se han tomado estas decisiones.

5.3.1. Trabajar con bases de datos Dada la gran cantidad de situaciones diferentes en las que se puede utilizar una base de

datos, existen muchos tipos y muchas formas de acceder a ellas.

Por eso, para que los programadores puedan acceder de forma estándar a una base de datos, los fabricantes suelen desarrollar junto con la base de datos el controlador ODBC (Open Database Connectivity – Conectividad abierta a base de datos) de acceso correspondiente, que proporciona al programador un conjunto de funciones para acceder al motor de la base.

Otros fabricantes con el fin de facilitar más las cosas, dotaron a sus herramientas de desarrollo de una nueva capa de software conocida como el motor de la base de datos, intercalada entre el código de la aplicación y el controlador ODBC. Un ejemplo es Microsoft Jet, el motor de la base de datos que proporciona Microsoft en muchos de sus productos. Se trata de una capa de software independiente de la aplicación que lo utiliza para acceder a la base de datos.

Finalmente en las herramientas de desarrollo actuales han proliferado los controles y los objetos de acceso a datos, los cuales establecen un puente entre la interfaz del usuario y el motor de la base de datos.

Visual Basic proporciona varias formas de acceso a bases de datos, entre otras las dos más importantes son:

• ADO (ActiveX Data Objects – Objetos ActiveX de acceso a datos). Este modelo es más sencillo y proporciona mejor integración con la tecnología de Microsoft y con otras tecnologías, una interfaz común para acceso a datos locales y remotos,

Page 129: DCSLLL

5 Programación

128

conjuntos de registros (recordsets) remotos y locales, una interfaz de enlace con los datos accesible para el usuario y un conjunto de registros jerárquicos.

• ADODC (ADO Data Control – Control de datos ADO) Permite crear una conexión con una base de datos de una forma fácil y rápida mediante objetos ActiveX de acceso a datos.

• DAO (Data Access Objects – Objetos de acceso a datos) El modelo de objetos DAO admite dos entornos diferentes de bases de datos o espacios de trabajo: MS Jet y ODBCDirect (acceso directo a ODBC). Microsoft Jet permite acceder a bases de datos Microsoft Access o bien a bases de datos Microsoft conectadas a ODBC. ODBCDirect permite tener acceso a servidores de bases de datos a través de ODBC sin cargar el motor de bases de datos Microsoft Jet.

Control Data

DAO

ODBCDirect

RDO

Administradorde ODBC

MS Jet

ControladorODBC

ControladorODBC

ControladorODBC

RDC Control ADO

ADO

OLE DB

Figura 48. Acceso a bases de datos

El motor JET (DAO) funciona bien en monousuario y en redes pequeñas teniendo problemas de bloqueo cuando varios usuarios acceden a una misma información. La ventaja de trabajar con el motor Jet es que no se necesita depender de ningún driver ODBC externo, que las aplicaciones son más sencillas y dan menos problemas de configuración.

El acceso a datos basado en ADO es adecuado para una gran amplia gama de aplicaciones cliente/servidor. Las principales ventajas son fácil utilización, gran velocidad, uso de poca memoria y poca utilización de disco.

En el libro del que se ha extraído esta información, se recomienda el uso de ADO explicando que las nuevas aplicaciones deben ser lo más sencillas posibles, tanto para el usuario como para el programador que debe soportarlas.

5.3.1.1. ADO El acceso a la base de datos mediante ADO es configurable. Lo primero es encontrar la

forma que mejor se adapta a nuestras necesidades.

Page 130: DCSLLL

5 Programación

129

Configuración de acceso - Crear registros La configuración de acceso a la base de datos depende principalmente de dos

parámetros:

• Tipo de cursor (CursorType): Sólo adelante (Forward Only), Keyset, Dinámico (Dynamic), Estático (Static)

• Tipo de bloqueo (LockType): Sólo lectura (Read only), Optimista (Optimistic), Pesimista (Pessimistic), Optimista por lotes (BatchOptimistic)

Cada elección conlleva unas ventajas e inconvenientes.

Se va a utilizar un cursor estático pues, aunque no permite observar los cambios que hacen otros usuarios en la base de datos de forma automática, sí que se puede refrescar a petición y sobretodo permite el uso de señaladores (bookmarks) para moverse libremente por los registros.

Como se trabaja con grandes cantidades de información, la selección del tipo de bloqueo viene determinada por la velocidad que nos permite cada uno. Recordemos que en el caso de trabajar con un archivo de documentación de 8192 etiquetas de dirección y un programa de 5000 líneas, se necesitaría crear 13192 registros en el momento de abrir el proyecto.

Para encontrar el mejor tipo de bloqueo, se ha realizado un programa que crea un determinado número de registros en una base de datos, para distintas configuraciones. En la misma tabla también se puede observar como la selección de cursor estático no tiene peores prestaciones que el cursor dinámico. Así se han obtenido los siguientes resultados:

Cursor Bloqueo Número reg. Tiempo (seg.)

Dinámico Pesimista 10000 66 Estático Pesimista 10000 60 Estático Optimista 10000 58 Estático Optimista por lotes 10000 6,8

Tabla 28. Velocidad de creación de registros en entorno ADO según configuración de acceso

Al necesitar una alta velocidad de acceso viendo los resultados, la única opción posible en la elección de bloqueo es usar optimista por lotes (batchoptimistic).

Este bloqueo consigue reducir el tiempo, pues trabaja sobre una copia de la base de datos en memoria interna y no directamente sobre la base de datos guardada en el disco duro, actualizándola sólo cuando le conviene al programador.

Método de acceso - Editar registros

Para acceder a los datos, se pueden utilizar dos métodos principalmente:

• Método “Find”: Devuelve el registro de la tabla que contiene la cadena indicada en el campo deseado. Como todas las tablas del proyecto contienen un campo con valores únicos, ya sea el número de dirección, de línea o de comentario, se puede buscar el registro que contiene el número requerido.

• Método “Absolute position”: Devuelve el registro de la tabla situado en la posición indicada. En el caso de que la tabla tenga los registros ordenados por el campo de valores únicos, caso de las zonas de memoria de usuario y de sistema,

Page 131: DCSLLL

5 Programación

130

se puede acceder directamente al registro indicando la posición, que coincidirá por tanto con el número buscado.

Para buscar qué método es más rápido, se ha desarrollado un programa de test, que realiza una consulta aleatoria de un número M de registros en una tabla de N registros. Así, se han obtenido los siguientes resultados:

N registros M registros Find (seg.) Absolute Position (seg.)

5000 1000 46,7 0,6 25000 1000 274,1 4,1

Tabla 29. Velocidad de edición de registros en entorno ADO según método de acceso

Se concluye que habría que trabajar con el método “Absolute Position” siempre que se pueda, y tratar de reducir el tamaño de la tabla al mínimo posible.

Visualización de datos El objeto de Visual Basic que permite visualizar los datos de un proveedor ADO se

llama DataGrid.

Hay que tener en cuenta, que los objetos proveedores de datos pueden trabajar de forma independiente con objetos que visualizan los datos, o pueden trabajar de forma combinada.

El trabajar de forma independiente, significa que cada uno trabaja directamente sobre una copia de la base de datos, así, para poder visualizar en el objeto de visualización los cambios realizados por programación, hay que actualizar la base de datos. Por lo que al final se pierde el tiempo que se ha ahorrado trabajando con un bloqueo en modo “Batchoptimistic”.

Es por eso que todos los objetos o funciones de programa trabajarán con el mismo proveedor de datos.

Esto presenta a su vez el problema de que los objetos de visualización se redibujan para cada uno de los cambios en la base de datos, lo que vuelve a relentizar el proceso de actualización de información. Tras varias pruebas, se ha determinado que lo mejor es desconectar temporalmente los objetos visuales del proveedor de datos mientras se producen las modificaciones por parte del programa, y conectarlos al acabar para que presenten los registros actualizados.

Problema Después de todos los estudios anteriores, apareció un problema.

Si se quiere añadir un nuevo registro, aunque se posicione la tabla en el registro anterior al que se quiere crear, éste se añade al final de la tabla, por lo que ésta se desordena.

El problema aparece cuando los métodos disponibles no permiten reordenar los registros de la base de datos, a no ser que se haga una actualización de la base de datos.

Aunque esto no represente un problema con el mapeado de memoria, sí que es un gran problema en el caso de las ventanas de edición de los ficheros de documentación. Recordemos que las tablas de memoria incluyen todas las posiciones en función del modelo, no pudiendo el usuario añadir nuevas, sin embargo, en las tablas de etiquetas y comentarios se pueden añadir nuevos registros en posiciones intermedias en reserva.

Page 132: DCSLLL

5 Programación

131

Conclusión Debido al problema anterior, no se puede utilizar la configuración de bloqueo optimista

por lotes ni por tanto el modelo ADO para acceder a los ficheros de documentación.

5.3.1.2. DAO El acceso a la base de datos mediante DAO, se hace por medio del motor Microsoft Jet

4.0 que permite trabajar con bases de datos Access versión 2000.

Este acceso no presenta tantas opciones de configuración como el anterior sistema, la configuración escogida coincide con las opciones por defecto: Acceso compartido en modo lectura y escritura.

Crear registros Para comprobar la velocidad de creación de registros, se ha realizado un programa que

crea N registros en una base de datos. Así se han obtenido los siguientes resultados:

N registros Tiempo (seg.)

5000 1,2 25000 2,8 100000 12,6

Tabla 30. Velocidad de edición de registros en entorno DAO

Como se puede observar, sorprendentemente la velocidad de acceso es mucho mayor que en el caso de ADO.

Método de acceso - Editar registros Para acceder a los datos, se pueden utilizar dos métodos principalmente:

• Método “Seek”: Equivale al método Find de ADO.

• Método “Move”: Se diferencia del método “Absolute position” de ADO en que realiza un desplazamiento relativo a la posición actual, hacia registros anteriores o posteriores.

Para comprobar la velocidad de edición de registros, se ha realizado un programa que realiza una consulta aleatoria de un número M de registros en una tabla de N registros. Así, se han obtenido los siguientes resultados expresados en segundos:

N registros M registros Seek (seg.) Move (seg.)

5000 1000 0,18 1,9 25000 1000 0,2 8,9 100000 1000 0,22 - 100000 100000 20,3 -

Tabla 31. Velocidad de edición de registros en entorno DAO

Se puede observar como es más rápido acceder con el método “Seek” que con el método “Move” pues el método “Move” requiere un desplazamiento a la primera posición y luego otro a la posición definitiva. Se podría mejorar la eficiencia, teniendo en cuenta la posición actual para ir al destino con un salto relativo a la misma. Sin embargo, como el método “Seek” es más rápido no merece la pena.

Page 133: DCSLLL

5 Programación

132

Visualización de datos El objeto de Visual Basic que permite visualizar los datos de un proveedor DAO se

llama DataBoundGrid (DBGrid) en modo “Bound” (Asociado). El modo asociado ofrece al programador las funciones de edición, adición y borrado de registros de la tabla asociada.

En este caso, el trabajar con el objeto DBGrid conectado al control DAO no empeora la velocidad de acceso ni modificación.

Conclusión El uso de los objetos DAO permite mayor velocidad de acceso que los objetos ADO y

aunque corresponde a una tecnología anterior, como permite trabajar con bases de datos Access 2000 es el elegido.

5.3.2. Trabajar con tablas en memoria interna

5.3.2.1. Crear registros Para determinar la velocidad de acceso a tablas en memoria interna, se han realizado

dos programas de test, al igual que en el caso de las bases de datos.

El primero crea un determinado número de registros, con los mismos campos que en los casos de bases de datos, para que la comparación sea correcta. Así se han obtenido los siguientes resultados.

Número reg. Tiempo (seg.)

5000 0,01 25000 0,01 100000 0,04

Tabla 32. Velocidad de creación de registros en tablas en memoria interna

5.3.2.2. Editar registros El segundo programa de test, realiza una consulta aleatoria de un número M de registros

en una tabla de N registros. Se han obtenido los siguientes resultados:

N registros M registros Tiempo (seg.)

5000 1000 0,01 25000 1000 0,01 100000 1000 0,01 100000 100000 0,35

Tabla 33. Velocidad de edición de registros en tablas en memoria interna

5.3.2.3. Visualización de datos Para visualizar datos de tablas de memoria, el control más apropiado es el

DataBoundGrid funcionando en modo “Unbound” (No asociado).

El modo no asociado exige que el programador escriba las rutinas de lectura, escritura, adición y borrado de los registros de la tabla relacionada. Para ello, inicializa ciertos parámetros que le indican al programador que es lo que necesita.

5.3.2.4. Conclusión Usando tablas internas, se consigue una gran velocidad de acceso a datos, a cambio de

una mayor complejidad de programación.

Page 134: DCSLLL

5 Programación

133

5.3.3. Toma de decisiones

5.3.3.1. Archivo de configuración Tal y como se detalla en el capítulo 4.6 F6 - 623 Software configuration *.cfg y en el

capítulo 5.6 Ventana de configuración (Frm_MDIChildConfiguracion), los datos a almacenar tienen las siguientes características:

Necesitan BD Tabla Justificación

Velocidad de acceso Baja Los datos son editados por el usuario a través de un formulario.

Edición externa al programa (exportar)

No Su valor está codificado en algunos casos, lo que confundiría al usuario.

Desarrollo de visualizadores propios

Si Los datos a representar exigen listas desplegables y opciones, objetos que no trabajan fácilmente asociados a bases de datos.

Tabla 34. Decisión de soporte para archivo de configuración

Por lo que se decide utilizar tablas.

5.3.3.2. Archivos de documentación Tal y como se detalla en el capítulo 4.3 F3 – Documentation functions y en el capítulo

5.7 Ventana de documentación (Frm_MDIChildDocumentacion), los datos a almacenar tienen las siguientes características:

Necesitan BD Tabla Justificación

Velocidad de acceso Baja Los datos son editados por el usuario a través de un formulario.

Edición externa al programa (exportar)

Si Es uno de los objetivos del proyecto.

Desarrollo de visualizadores propios

No Los datos se adaptan perfectamente a los objetos ofrecidos por Visual Basic para trabajar asociados a BD.

Tabla 35. Decisión de soporte para archivos de documentación

Por lo que se decide utilizar bases de datos.

Page 135: DCSLLL

5 Programación

134

5.3.3.3. Archivo de programa Tal y como se detalla en el capítulo 4.2 F2 – 620 Stand alone loader (*.ldr) y en el

capítulo 5.9 Ventana de programa (Frm_MDIChildPrograma), los datos a almacenar tienen las siguientes características:

Necesitan BD Tabla Justificación

Velocidad de acceso Alta Los datos son leídos por el programa en la simulación, requiriendo la mayor velocidad posible.

Edición externa al programa (exportar)

No Su contenido está codificado, lo que confundiría al usuario.

Desarrollo de visualizadores propios

Si La representación de los datos exige un entorno gráfico, no ofrecido por Visual Basic para trabajar asociado a una base de datos.

Tabla 36. Decisión de soporte para archivo de programa

Por lo que se decide utilizar tablas.

5.3.3.4. Memoria de usuario y de sistema Tal y como se detalla en el capítulo 4.6 F6 - 623 Software configuration *.cfg y en el

capítulo 5.8 Ventana de memoria interna (Frm_MDIChildMemoria), los datos a almacenar tienen las siguientes características:

Necesitan BD Tabla Justificación

Velocidad de acceso Alta Los datos son leídos por el programa en la simulación, requiriendo la mayor velocidad posible.

Edición externa al programa (exportar)

Si No es un objetivo pero podría facilitar el trabajo al usuario.

Desarrollo de visualizadores propios

No Los datos se adaptan perfectamente a los objetos ofrecidos por Visual Basic para trabajar asociados a BD.

Tabla 37. Decisión de soporte para memoria de usuario y de sistema

A pesar de que los puntos a favor sean más en el caso de bases de datos que en tablas, la necesidad de una gran velocidad de edición y consulta de los datos hace que la decisión sea utilizar tablas.

Page 136: DCSLLL

5 Programación

135

5.4. Ventana de presentación (Frm_Splash)

Figura 49. Captura de la ventana de presentación

Aparece unos instantes al comienzo de la ejecución del programa, presentando información del programa.

• Título del programa

• Versión

• Autor

• Finalidad

• Fecha

Mientras, en segundo plano, continúa la carga del programa.

5.4.1. Procedimientos y funciones

5.4.1.1. Private Sub Form_Load ( ) Procedimiento ejecutado por el sistema cuando la función de inicio (Main) solicita

cargar el formulario

Al cargarse la ventana de presentación, se comienza una temporización que da tiempo al sistema para cargar la ventana principal (Frm_MDI) en segundo plano.

5.4.1.2. Private Sub TimeSplash_Timer ( ) Procedimiento ejecutado por el sistema cuando se acaba la temporización.

Una vez finalizado el tiempo, descarga la ventana de presentación.

Page 137: DCSLLL

5 Programación

136

5.5. Ventana principal (Frm_MDI)

Figura 50. Captura de la ventana principal

Es la ventana que se encarga de controlar la ejecución global del programa. Contiene el menú, la barra de herramientas y la barra de estado.

Realiza las siguientes funciones

• Gestión de menús.

• Gestión de barras de herramientas.

• Gestión de ventanas MDIChild.

• Gestión de la barra de estado.

• Gestión de la barra de progreso.

5.5.1. Documentación y decisiones

5.5.1.1. Gestión de ventanas MDIChild Cuando Visual Basic ejecuta un programa, carga los módulos que contienen los

procedimientos comunes, pero no carga los formularios MDIChild hasta que son requeridos.

Al ser los formularios MDIChild los encargados de interactuar con el proyecto abierto, hay que decidir cómo trabajar con ellos en función de si el proyecto está abierto o cerrado. Existen tres opciones:

• Cargar los formularios MDIChild desde el principio y crear dos rutinas, una para inicializarlos cuando se abre el proyecto y otra para desactivarlos cuando se cierra.

• Cargar los formularios cuando se abre el proyecto y descargarlos cuando se cierra.

• Cargar los formularios cuando el usuario los requiera posteriormente a la apertura del proyecto y descargarlos cuando se cierra el proyecto.

No se contempla la opción de descargar el formulario cuando el usuario los oculte manteniendo el proyecto abierto, pues se perderían los datos del proyecto actual debiéndolos cargar cada vez.

Page 138: DCSLLL

5 Programación

137

Como los cambios en un formulario pueden afectar a otros, es preferible no usar la tercera opción para que los cambios puedan realizarse sin los problemas que se presentarían al intentar actualizar un formulario todavía no cargado.

Utilizando la segunda y no la primera opción, se libera memoria cuando no hay un proyecto abierto y no es necesario crear rutinas de apoyo pues las variables se inicializan automáticamente cada vez que se carga el formulario al abrir un nuevo proyecto.

Una vez todos los formularios están cargados, es suficiente trabajar posteriormente cambiando el valor del parámetro “Visible” para que aparezcan o desaparezcan cuando el usuario los requiera.

5.5.1.2. Gestión de menús La mayoría de los programas que trabajan bajo el sistema Windows tienen el menú

“Ver” que permite seleccionar que ventana visualizar o, si ya estaba abierta, ponerla en primer plano, utilizándose el botón en la esquina superior derecha marcado con una X para cerrarla.

Para controlar si un formulario está visible o no se crea una variable global que almacene el estado.

Como también se dispone de la pestaña “Ventana” para situar en primer plano cualquiera de las ventanas ya abiertas, se considera que es mejor trabajar de forma que el menú “Ver” indique las ventanas abiertas permitiendo abrir las cerradas y cerrar las abiertas y ofrecer mayor facilidad de manejo.

De lo expuesto anteriormente se concluye que el menú debe de incluir las entradas:

• “Proyecto”: Permite seleccionar si se quiere abrir, cerrar, guardar un proyecto o salir del programa. Además permitirá al usuario llamar al programa MS-DOS Loader con el programa actual para facilitar la edición.

- “Abrir“

- “Cerrar“

- “Editar“

- “Guardar uno a uno“

- “Guardar todos“

- “Cerrar“

• “Ver”: Permite seleccionar que ventana desea ver u ocultar.

- “Programa“

- “Configuración“

- “Documentación“

- “Simulación“

- “Mapeado de memoria“

• “Ventana” Permite cambiar la presentación de las ventanas abiertas a las opciones comunes (cascada, mosaico,…) o poner en primer plano la seleccionada.

- “Cascada“

- “Mosaico horizontal“

Page 139: DCSLLL

5 Programación

138

- “Mosaico vertical“

- “Organizar iconos“

En el caso de que no exista un proyecto abierto, todas las opciones del menú excepto la de abrir deben de estar desactivadas. Se necesita una variable global que controle si hay un proyecto abierto o no, para habilitar o no habilitar las opciones de menú correspondientemente.

Sin embargo, deben de estar deshabilitadas los formularios de simulación y de mapeado de memoria si no se permite la simulación del proyecto abierto, debido a que el modelo de LM seleccionado no corresponde al 620-25 o 620-35. Se necesita una variable global que controle si se permite la simulación, para habilitar o no habilitar las opciones de menú correspondientemente.

5.5.1.3. Barra de herramientas Las opciones de depuración del programa como por ejemplo ejecutar una línea, van a

ser utilizadas frecuentemente, por lo que es preferible que estén en una barra de herramientas y no en el menú.

Hay que tener en cuenta, que el usuario puede estar consultando como afecta la ejecución de cada línea en los valores de las tablas de memoria, en las gráficas de la simulación, … por lo que esta barra de herramientas debe de estar visible en todo momento y no vinculada a la visualización de ningún formulario MDIChild.

Las ordenes de depuración y por tanto los botones de la barra de herrmientas son:

• “Ejecutar una línea”

• “No ejecutar una línea”

• “Ejecutar un ciclo”

• “Ejecución contínua”

• “Reiniciar simulación”

Al igual que ocurría en el caso del menú, si no hay un proyecto abierto, las opciones de la barra de tareas deben de permanecer deshabilitadas. Sin embargo, también deben de estar deshabilitadas si no se permite la simulación del proyecto abierto, debido a que el modelo de LM seleccionado no corresponde al 620-25 o 620-35.

5.5.1.4. Barra de estado Para que el usuario pueda recibir información de ciertos eventos que el programa

considere oportuno destacar, es necesario situar en la parte inferior una barra de estado.

Se ha decidido que la frase de información se visualice hasta que sea sobrescrita por una más reciente o transcurrido un tiempo máximo. Con la temporización se evita que en aquellos procesos de muy corta duración, la información desaparezca antes de poder leerla.

5.5.1.5. Barra de progreso Para que el usuario pueda recibir información del progreso en la apertura de un proyecto

o en la simulación es necesario situar en la parte inferior una barra progreso.

5.5.2. Variables globales

Bool_MDIChildConfiguracionVisible: Indica si la ventana configuración está visible.

Page 140: DCSLLL

5 Programación

139

Bool_MDIChildDocumentacionVisible: Indica si la ventana documentación está visible.

Bool_MDIChildProgramaVisible: Indica si la ventana programa está visible.

Bool_MDIChildSimulacionVisible: Indica si la ventana simulación está visible.

Bool_MDIChildMemoriaVisible: Indica si la ventana memoria está visible.

Bool_ProyectoAbierto: Indica si existe un proyecto abierto.

Bool_EjecucionHabilitada: Indica si está permitida la simulación para el modelo de LM seleccionado.

Str_RutayNombreCFG: Contiene la ruta y nombre del archivo *.cfg abierto.

5.5.3. Procedimientos y funciones

5.5.3.1. Private Sub MDIForm_Load() Inicialización de la ventana MDI. Si se ha llamado al programa seleccionando un

fichero *.cfg se carga el proyecto que representa.

Flujograma Configura aspecto formulario desde el registro

Se ha ejecutado el programa seleccionando un archivo *.cfg

Si Recuperar nombre fichero desde la línea de comandos

Abrir proyecto (Sub_AbrirProyecto)

Actualizar menú (Sub_ActualizarMenu)

Fin

5.5.3.2. Private Sub MDIForm_QueryUnload(Cancel As Integer, UnloadMode As Integer)

Pregunta al usuario si está seguro de abandonar el programa, en caso afirmativo si hay un proyecto abierto pregunta si quiere guardar los cambios.

Flujograma Presentar pregunta: “Desea abandonar el programa”

Si Hay un proyecto abierto

Si Cerrar proyecto (Sub_cerrarProyecto)

No Cancelar descarga

Fin

5.5.3.3. Private Sub MDIForm_Unload() Descarga el formulario guardando la configuración de aspecto del formulario en el

registro.

Flujograma

Guarda aspecto de la ventana en el registro

Fin

Page 141: DCSLLL

5 Programación

140

5.5.3.4. Public Sub Sub_ActualizarMenu ( ) Actualiza el estado de las opciones de menú y barras de herramientas en función de si

hay un proyecto abierto o no y si se permite o no la simulación para el modelo de LM seleccionado.

Flujograma Hay un proyecto abierto (Bool_ProyectoAbierto)

Si Habilita comandos del menú “Proyecto”

Habilita comandos del menú “Ver”

Está visible ventana configuración (Bool_MDIChildConfiguracionVisible)

Si Chequea comando de menú

No Deschequea comando de menú

IDEM para ventanas: Documentación (Bool_MDIChildDocumentacionVisible)

Programa (Bool_MDIChildProgramaVisible)

Simulación (Bool_MDIChildSimulacionVisible)

Memoria (Bool_MDIChildMemoriaVisible)

Habilita comandos de menú ventana

Se permite la simulación (Bool_EjecucionHabilitada)

Si Habilita botones de la barra de herramientas

No Inhabilita comandos de menú “Proyecto” excepto “Abrir”

Inhabilita menú “Ver”

Inhabilita menú “Ventana”

Inhabilita barra de herramientas

Fin

5.5.3.5. Private Sub Mnu_PAbrir_Click()

Procedimiento ejecutado por la opción del menú “Proyecto/Abrir”.

Abre un nuevo proyecto permitiendo al usuario seleccionar el archivo *.cfg.

Si hay un proyecto abierto solicita al usuario si quiere abandonarlo.

Flujograma Hay un proyecto abierto (Bool_ProyectoAbierto)

Si Cerrar proyecto

El usuario ha querido cerrar el proyecto actual (Bool_ProyectoAbierto)

No Abandonar procedimiento

Si Presentar ventana de selección del archivo *.cfg

Existe el fichero

Si Abrir Proyecto (Sub_ABrirProyecto)

No Abandonar procedimiento

Page 142: DCSLLL

5 Programación

141

Actualizar menú (Sub_ActualizarMenu)

Fin

5.5.3.6. Private Sub Mnu_PCerrar_Click() Procedimiento ejecutado por la opción del menú “Proyecto/Cerrar”.

Si hay un proyecto abierto solicita al usuario si quiere cerrar y guardar el proyecto.

Flujograma Cerrar proyecto (Sub_CerrarProyecto)

Actualizar menú (Sub_ActualizarMenu)

Fin

5.5.3.7. Private Sub Mnu_PEditar_Click() Procedimiento ejecutado por la opción del menú “Proyecto/Editar”.

Abre el programa MS-DOS Loader con el archivo *.cfg del proyecto en curso, para facilitar al usuario la edición de las líneas de programa.

Para ello genera y ejecuta el archivo *.bat con las ordenes adecuadas:

C:> cd <Ruta archivo *.cfg>

C:> call loader <Nombre archivo *.cfg>

Es necesario que el archivo *.cfg esté en el mismo directorio que el programa Loader.exe, condición habitual al trabajar con el programa MS-DOS Loader.

Flujograma Extraer ruta del archivo *.cfg (Str_RutayNombreCFG)

Extraer nombre del archivo *.cfg (Str_RutayNombreCFG)

Generar archivo *.bat

Ejecutar archivo *.bat

Fin

5.5.3.8. Private Sub Mnu_PGuardartodos_Click() Procedimiento ejecutado por la opción del menú “Proyecto/Guardar Todos”.

Escribe todos los archivos del proyecto a partir de los datos almacenados en memoria.

Flujograma Escribir ficheros (Sub_EscribirFicheros)

Fin

5.5.3.9. Private Sub Mnu_PGuardarunoauno_Click() Procedimiento ejecutado por la opción del menú “Proyecto/Guardar uno a uno”.

Solicita al usuario qué archivos del proyecto desea escribir a partir de los datos almacenados en memoria.

Flujograma Escribir ficheros uno a uno (Sub_EscribirFicherosUnaaUno)

Page 143: DCSLLL

5 Programación

142

Fin

5.5.3.10. Private Sub Mnu_PSalir_Click() Procedimiento ejecutado por la opción del menú “Proyecto/Salir”.

Cierra el programa.

En caso de que haya un proyecto abierto, el evento QueryUnload se encarga de solicitar al usuario si quiere realmente cerrar y guardar el proyecto.

Flujograma Cerrar programa

Fin

5.5.3.11. Private Sub Mnu_VConfiguracion_Click() Procedimiento ejecutado por la opción del menú “Ver/Configuración”.

Presenta u oculta la ventana configuración.

Flujograma La ventana está visible (Bool_MDIChildConfiguracionVisible)

Si Oculta la ventana

Indica ventana no visible

No Presenta la ventana

Indica ventana visible

Actualizar menú (Sub_ActualizarMenu)

Fin

IDEM para procedimientos:

• Private Sub Mnu_VDocumentacion_Click() (Bool_MDIChildDocumentacionVisible)

• Private Sub Mnu_VPrograma_Click() (Bool_MDIChildProgramaVisible)

• Private Sub Mnu_VSimulacion_Click() (Bool_MDIChildSimulacionVisible)

• Private Sub Mnu_VMemoria_Click() (Bool_MDIChildMemoriaVisible)

5.5.3.12. Private Sub Mnu_VCascada_Click() Ordena las ventanas MDIChild en cascada.

5.5.3.13. Private Sub Mnu_VMosaicoHorizontal_Click() Ordena las ventanas MDIChild en mosaico horizontal.

5.5.3.14. Private Sub Mnu_VMosaicoVertical_Click() Ordena las ventanas MDIChild en mosaico vertical.

5.5.3.15. Private Sub Sub_AbrirProyecto() Abre un proyecto.

Flujograma Inicializa tablas internas (Sub_InicializarTablas)

Page 144: DCSLLL

5 Programación

143

Abrir archivo de configuración (Sub_LeerFicheroConfiguracion)

Error

Si Abandonar procedimiento

Crear la base de datos (Sub_CrearBasedeDatos)

Conectar la base de datos (Sub_ConectarBasedeDatos)

Dimensionar tablas mem. usuario (Sub_DimensionarTablasMapeadodeMemoria)

Abrir archivos del proyecto (Sub_LeerFicherosProyecto)

Cargar ventanas MDIChild

Indicar que hay un proyecto abierto (Bool_ProyectoAbierto)

Fin

5.5.3.16. Private Sub Sub_CerrarProyecto() Cierra el proyecto abierto.

Pregunta si el usuario quiere guardar los cambios realizados o cerrar sin guardarlos.

Flujograma El usuario quiere guardar cambios

Si Guardar ficheros uno a uno (Sub_EscribirFicherosUnoaUno)

Descargar ventanas MDIChild

Borrar base de datos (Sub_BorrarBasedeDatos)

Borrar tablas internas (Sub_InicializarTablas)

Indicar que no hay proyecto abierto (Bool_ProyectoAbierto)

Fin

5.5.3.17. Private Sub TB_Simular_buttonClick(ByVal Button As MSComctlLib.Button) Procedimiento ejecutado al pulsar cualquier botón de la barra de herramientas.

Indica al módulo de simulación (Mdl_Simular) la orden seleccionada por el usuario.

Como cualquiera de estas ordenes implica un nuevo paso en la simulación, se deben de refrescar los formularios que pudieran verse afectados, por el cambio por ejemplo del valor de una dirección.

Flujograma Orden seleccionada

“Simular Linea” Simular una línea (Sub_Simular)

“Saltar Linea” Saltar una línea (Sub_Simular)

“Simular Ciclo” Simular un ciclo completo (Sub_Simular)

“Simular” Simular hasta alcanzar tiempo total de simulación (Sub_Simular)

“Reset” Reiniciar simulación (Sub_Simular)

Actualizar formularios afectados (Sub_ActualizarFormularios)

Fin

Page 145: DCSLLL

5 Programación

144

5.5.3.18. Public Sub Sub_ActualizarBarradeProgreso(Int_Valor As Integer) Representa en la barra de progreso el valor recibido que corresponde con el porcentaje

(0 a 100) a visualizar.

5.5.3.19. Public Sub Sub_ActualizarBarradeEstado(Str_Texto As String) Muestra la cadena de texto recibida como información al usuario en la barra de estado.

La cadena de texto estará visible durante un tiempo máximo, o si es sobrescrita.

Flujograma Escribir cadena de texto

Comenzar temporización tiempo de visualización

Fin

5.5.3.20. Private Sub Time_MDI_Timer() Una vez finalizado el tiempo, borra la información de la barra de estado.

Flujograma Detener temporización

Borrar cadena de texto

Fin

Page 146: DCSLLL

5 Programación

145

5.6. Ventana de configuración (Frm_MDIChildConfiguracion)

Figura 51. Captura de la ventana de configuración

Ventana MDIchild.

Aparece a solicitud del usuario por medio del menú.

Ventana de edición de los datos de configuración (archivo *.cfg) del proyecto abierto.

5.6.1. Documentación y decisiones La decodificación de este archivo se detalla en el apartado 4.6 F6 - 623 Software

configuration *.cfg.

Se ha mantenido la distribución e idioma del programa MS-DOS Loader a la hora de agrupar y presentar los datos de configuración, por ello, esta ventana presenta cuatro pestañas:

• Paths and Files

• Operational Modes

• System Type and File Loads

• Stand-Alone Parameters

A cada una de las pestañas le corresponde un marco con objetos de texto, celdas de chequeo y de opción que contienen los datos de configuración, de tal forma que se hace visible el marco que corresponde a cada una de las pestañas ocultando el resto.

Solo se va a permitir modificar aquellos campos, que tienen una aplicación en el programa de simulación. Los demás deben permanecer deshabilitados.

Page 147: DCSLLL

5 Programación

146

Como son parámetros que determinan la configuración del sistema, se considera que es mejor que los cambios no tengan efecto hasta que el usuario los confirme. Por lo que se van a añadir los botones “Aceptar”, “Aplicar” y “Cancelar” cambios.

Tal y como se explica en el capítulo 5.15 Módulo de soporte tablas internas (Mdl_TablasInternas) la información de este fichero está almacenada en una tabla de memoria interna llamada “Con_Programa”, a la que se accede a través de las funciones del módulo.

Observando las tablas Tabla 22. Estructura del archivo *.cfg (1/2) y Tabla 23. Estructura del archivo *.cfg (2/2), existen tres tipos de parámetros:

• Cadenas de texto • Distintas opciones codificadas con valores enteros (codificación simple) • Mapeado de memoria

5.6.1.1. Cadenas de texto Estos parámetros se van a representar en la ventana, con controles “TextBox”.

5.6.1.2. Codificación simple Son parámetros que han sufrido una codificación en la que cada valor entero

corresponde a uno de los valores que puede tomar el parámetro. Por ejemplo, el caso del parámetro “Auto Clear”: un 0 significa OFF, un 1 significa ON.

Se van a representar por medio de controles “OptionButton”.

5.6.1.3. Mapeado de memoria De acuerdo a la Tabla 27. Mapeado de memoria en función del modelo de Logic

Manager seleccionado, se pueden seleccionar distintos valores de tamaño de memoria de programa, de registros y de E/S reales.

Por eso, estos cuatro parámetros se representan por medio de controles “ComboBox”, que actualizan las opciones de la lista desplegable en función del modelo seleccionado.

5.6.2. Procedimientos y funciones

5.6.2.1. Private Sub Form_Load ( ) Inicializa el formulario, lo sitúa en posición y carga los datos de la tabla

correspondiente.

Flujograma Configura aspecto del formulario desde el registro

Selecciona pestaña de inicio, presenta marco relacionado y oculta el resto

Rellena controles con los datos de la tabla interna (Sub_RestauraControles)

Fin

5.6.2.2. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) Si es el usuario quien solicita descargar la ventana (botón ), se cancela descarga y

sólo se oculta para evitar cargar otra vez los datos la próxima vez.

Flujograma Ha sido el usuario

Page 148: DCSLLL

5 Programación

147

Si Ocultar formulario

Rellena controles con los datos de la tabla interna

Indicar formulario oculto

Actualizar información estado ventana en el menú (Sub_ActualizarMenu)

Cancelar la descarga

Fin

5.6.2.3. Private Sub Form_Unload() Descarga la ventana guardando el aspecto de la ventana en el registro.

Flujograma Guarda aspecto del formulario en el registro

Fin

5.6.2.4. Private Sub TS_Configuracion_Click ( ) Cuando el usuario selecciona una pestaña diferente, presenta el marco que contiene los

datos de la pestaña seleccionada, y oculta todos los demás.

Flujograma Pestaña seleccionada

“Paths & Files”

Presenta marco “Paths & Files”

Oculta el resto de marcos

IDEM para pestañas: “Operacional Modes”

“System type and file loads”

“Stand-Alone parameters”

“Node Names”

Fin

5.6.2.5. Private Sub Cmd_Aceptar_Click ( ) Modifica los datos de la tabla interna con el valor almacenado en los objetos editables,

para no perder tiempo reescribiendo los campos que no se pueden modificar y oculta el formulario.

Hay que tener en cuenta que el usuario puede haber cambiado los controles “Register size” y “Real I/O size”, que configuran el mapeado de memoria en función del modelo de LM. En ese caso, es necesario redimensionar las tablas de mapeado de memoria.

Flujograma

Guardar datos de controles editables en la tabla interna (Sub_GuardarControles)

Ocultar formulario

Indicar formulario oculto

Fin

Page 149: DCSLLL

5 Programación

148

5.6.2.6. Private Sub Cmd_Aplicar_Click ( ) Actúa de igual forma que el botón Aceptar solo que no oculta el formulario.

Guardar datos de controles editables en la tabla interna (Sub_GuardarControles)

Fin

5.6.2.7. Private Sub Cmd_Cancelar_Click ( ) Restaura los controles con los datos de la tabla interna y oculta el formulario.

Flujograma Rellena controles con los datos de la tabla interna (Sub_RestauraControles)

Ocultar formulario

Indicar formulario oculto

Fin

5.6.2.8. Private Sub Sub_RestauraControles() Rellena los controles con los datos de la tabla interna.

Flujograma Lee primer registro configuración de la tabla interna

Actualiza control

IDEM para todos los parámetros de configuración

Si el parámetro es el modelo de LM

Rellenar las listas desplegables de los controles de mapeado de memoria (Sub_RellenaCombosSAPsegunModeloLM)

Fin

5.6.2.9. Private Sub Sub_GuardarControles() Modifica los datos de la tabla interna con el valor almacenado en los objetos editables,

para no perder tiempo reescribiendo los campos con valores de los objetos que no se pueden modificar.

Los cambios en este formulario que afectan al resto de módulos son:

• Modelo de LM: solo en los casos de 620-25 y 620-35 se permite la simulación.

• Mapeado de memoria: se deben redimensionar las tablas de memoria de registros y estados de E/S.

Si se ha cambiado el mapeado de memoria se deben de actualizar los formularios relacionados.

Flujograma Lee control

Escribe primer registro de configuración en la tabla interna

IDEM para todos los parámetros de configuración

Modelo de LM distinto a 620-25 o 620-35

Si Inhabilitar ejecución (Bool_EjecucionHabilitada)

Page 150: DCSLLL

5 Programación

149

No Habilitar ejecución (Bool_EjecucionHabilitada)

Ha cambiado parámetro tamaño memoria de registros

Si Actualizar módulos y form. (Sub_DimensionarTablaMemoriadeUsuario)

Ha cambiado parámetro tamaño memoria de E/S reales

Si Actualizar módulos y form. (Sub_DimensionarTablaMemoriadeUsuario)

Fin

5.6.2.10. Private Sub Cmb_SAP_Click(Index As Integer) Si se ha modificado el modelo de LM, se cambian las opciones de las listas deplegables

de los controles tamaño de memoria de programa, de registros y de estados E/S, de acuerdo a la Tabla 27. Mapeado de memoria

Flujograma Rellenar lista de los controles de mapeado de memoria

(Sub_RellenaCombosSAPsegunModeloLM)

Fin

5.6.2.11. Private Sub Sub_RellenaCombosSAPsegunModeloLM() Rellena los controles ComboBox tamaño de memoria de programa, de registros y de

estados E/S con las opciones posibles en función del modelo de LM.

Flujograma Borrar contenido anterior de los controles

Modelo de LM

“620-06”

Opciones tamaño memoria de programa = 2048

Opciones tamaño registros = 256

Opciones tamaño E/S reales = 192

IDEM para resto de modelos

Fin

Page 151: DCSLLL

5 Programación

150

5.7. Ventana de documentación (Frm_MDIChildDocumentacion)

Figura 52. Captura de la ventana de documentación

Ventana MDIchild.

Aparece a solicitud del usuario por medio del menú.

Ventana de edición de los datos contenidos en los archivos de documentación del proyecto abierto.

*.lbl - Address_label – Etiquetas de direcciones

*.ace - Address_comment – Comentarios de direcciones

*.lce - Line_comment - Comentarios de líneas de programa

*.skp - Skip_label – Etiquetas de líneas de salto

*.jsr - Subroutine_label – Etiquetas de líneas de subrutina

*.bce - Bit_Comment – Comentarios de bit

*.blb - Bit_label – Etiquetas de bit

Es por esto, que la ventana presenta siete pestañas.

A cada una de las pestañas le corresponde un control de visualización (DataBoundGrid) que permite editar los datos del archivo de documentación correspondiente.

Ofrece la opción de exportar e importar la base de datos interna del programa en una externa editable por el usuario, siendo éste uno de los objetivos del proyecto.

En un recuadro de texto el usuario puede escribir el número deseado para realizar una localización rápida del elemento.

Page 152: DCSLLL

5 Programación

151

5.7.1. Documentación y decisiones La decodificación de estos archivos se detalla en el apartado 4.3 F3 – Documentation

functions.

Tal y como se justifica en el apartado 5.3 ¿Bases de datos o tablas en memoria interna?, los datos de los archivos de documentación se guardan en una base de datos temporal en formato Access 2000.

El control DAO de Visual Basic que permite acceder a cada una de estas tablas es el control Data, mientras que el control que permite visualizar los datos de cada una de estas tablas es el control DataBoundGrid en modo Bound.

Para realizar este formulario, se pensaron tres opciones: • Un control DataBoundGrid para representar los datos de las 7 tablas. • Dos controles DataBoundGrid. Uno para representar las 4 tablas de etiquetas, y

otro para representar las 3 tablas de comentarios. • Siete controles DataBoundGrid. Uno para cada una de las tablas.

Como las tablas de comentarios tienen distintos campos de las de etiquetas, el utilizar un solo control obliga a reconfigurarlo con cada nueva selección.

Utilizando la segunda opción, con solo usar un control más, se soluciona ese problema, pues existe un control configurado para cada tipo de tabla. Sin embargo, presenta un problema que también tiene la opción anterior: al cambiar temporalmente a otra pestaña el registro que estaba seleccionado se pierde. Aunque se intentó solucionarlo implementando una tabla que guardase la posición del registro seleccionado en cada pestaña, el funcionamiento era muy errático debido a las tablas sin datos.

Por todo ello, se implementó la tercera opción. Al utilizar un control dedicado para cada tabla, además de facilitar la programación, se resuelven todos los problemas anteriores aunque sea a costa de aumentar las líneas de código.

Para facilitar la selección del registro a utilizar (hay que tener en cuenta que pueden existir 8192) se va añadir un recuadro de texto en el que el usuario podrá escribir el número de dirección deseada.

5.7.2. Procedimientos y funciones

5.7.2.1. Private Sub Form_Load()

Inicializa el formulario, lo sitúa en posición y conecta los controles Data a la base de datos.

Flujograma Conecta los controles Data a la base de datos (Sub_ConectarFrmDocumentacion)

Configura aspecto formulario desde el registro

Configura aspecto controles DataBoundGrid

Selecciona pestaña de inicio

Fin

5.7.2.2. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) Si es el usuario quien solicita descargar la ventana (botón ), se cancela descarga y

sólo se oculta para evitar cargar otra vez los datos la próxima vez.

Page 153: DCSLLL

5 Programación

152

Flujograma Ha sido el usuario

Si Ocultar formulario

Indicar formulario oculto

Actualizar información estado ventana en el menú (Sub_ActualizarMenu)

Cancelar la descarga

Fin

5.7.2.3. Private Sub Form_Unload(Cancel As Integer) Descarga la ventana guardando el aspecto de la ventana en el registro.

Flujograma Guarda aspecto de la ventana en el registro

Fin

5.7.2.4. Private Sub Form_Resize() Se hace que el control DataBoundGrid ocupe la máxima altura y anchura posible, en

función del tamaño del formulario, a no ser que se supere un tamaño mínimo.

Flujograma Altura formulario mayor o igual a alto mínimo

Si Calcular y aplicar altura a DBG’s del formulario

Calcular y aplicar situación resto de elementos

No Aplicar altura mínima a DBG’s

Aplicar posición mínima al resto de elementos

Anchura formulario mayor o igual a ancho mínimo

Si Calcular y aplicar anchura a DBG’s del formulario

No Aplicar anchura mínima a DBG’s

Fin

5.7.2.5. Private Sub TS_Documentacion_Click() Cuando el usuario selecciona una pestaña diferente, presenta el control DataBoundGrid

que contiene los datos de la pestaña seleccionada, y oculta todos los demás.

Flujograma

Ocultar todos los controles DBG

Pestaña seleccionada

“Address Label” Hace visible el control DBG asociado a la tabla “Address Label”

IDEM para pestañas: “Bit label”

“Skip label”

“Subroutine label”

Page 154: DCSLLL

5 Programación

153

“Address comment”

“Bit comment”

“Line comment”

Fin

5.7.2.6. Private Sub Txt_Ira_Change() Busca en la tabla de documentación seleccionada, el registro con el número de etiqueta

o de comentario que el usuario ha escrito.

Documentación y decisiones El trabajar con objetos Data y DBG asociados en modo Bound permite utilizar las

funciones de búsqueda Seek que implementan, para poder localizar el registro sin tener que escribir código adicional.

En caso de que no exista un registro con el número buscado, la tabla permanece en el registro actual.

Flujograma El texto escrito es numérico

Sí Pestaña seleccionada

“Address Label” Buscar registro con campo “NUMERO” = texto

IDEM para pestañas: “Bit label”

“Skip label”

“Subroutine label”

“Address comment”

“Bit comment”

“Line comment”

Fin

5.7.2.7. Private Sub Sub_ConectarFrmDocumentacion() Conecta los objetas Data en el formulario documentación a las tablas correspondientes

de la base de datos temporal.

Documentación y decisiones Como la base de datos que contiene los datos de documentación es creada por el

programa cuando se abre el proyecto antes de la carga del formulario, se podría trabajar sin esta función escribiendo en tiempo de diseño los datos de conexión en el control, pues no se produciría ningún error.

Se ha optado, sin embargo, por escribir estos datos de conexión posteriormente, para así poder crear la base de datos en el directorio temporal por defecto configurado en el sistema y no en una ruta fija, como por ejemplo “c:\temp”, que podría no existir en el ordenador de instalación.

Flujograma Conectar control Data a la tabla Etiquetas dirección (Rst_EtiDir)

Page 155: DCSLLL

5 Programación

154

Situar control Data en la primera posición

IDEM para controles:

Data_EtiquetasBit

Data _EtiquetasSalto

Data _EtiquetasSubrutina

Data _ComentariosBit

Data _ComentariosDireccion

Data _ComentariosLinea

5.7.2.8. Private Sub Cmd_ExportarMDB_Click() Copia la base de datos interna en la dirección que seleccione el usuario.

Flujograma Presentar cuadro diálogo seleccionar nombre fichero destino *.mdb

Nombre correcto

No Abandonar el procedimiento

Exportar base de datos (Sub_ExportarMDB)

Fin

5.7.2.9. Private Sub Cmd_ImportarMDB_Click() Copia la base de datos de la ruta seleccionada por el usuario en la base de datos interna.

Flujograma Advertir al usuario de que se borrarán los datos temporales

El usuario desea continuar

No Abandonar el procedimiento

Presentar cuadro diálogo seleccionar nombre fichero origen *.mdb

Nombre correcto

No Abandonar el procedimiento

Importar base de datos (Sub_ImportarMDB)

Fin

5.7.2.10. Private Sub DBG_EtiquetasDireccion_ AfterUpdate () Una vez modificado un registro, se refresca el objeto DataBoundGrid. Así, en el caso de

que se haya modificado la dirección, se reordenan los registros.

Flujograma Refrescar objeto DataBoundGrid Etiquetas dirección (DBG_EtiquetasDireccion)

Fin

IDEM para procedimientos:

DBG_EtiquetasBit

Page 156: DCSLLL

5 Programación

155

DBG _EtiquetasSalto

DBG _EtiquetasSubrutina

DBG _ComentariosBit

DBG _ComentariosDireccion

DBG _ComentariosLinea

5.7.2.11. Private Sub DBG_EtiquetasDireccion_ AfterUpdate () Los objetos DataBoundGrid trabajan de igual forma que Access, ya que los nuevos

registros se introducen mediante la última fila.

Una vez añadido un nuevo registro, se refresca el objeto DataBoundGrid. Así, se mantienen ordenados los registros por el campo dirección.

Flujograma Refrescar objeto DataBoundGrid Etiquetas dirección (DBG_EtiquetasDireccion)

Fin

IDEM para procedimientos:

DBG_EtiquetasBit

DBG _EtiquetasSalto

DBG _EtiquetasSubrutina

DBG _ComentariosBit

DBG _ComentariosDireccion

DBG _ComentariosLinea

5.7.2.12. Private Sub DBG_EtiquetasDireccion_LostFocus() Antes de pasar el enfoque a otro control actualiza los datos que se estaban editando en

ese momento.

Documentación y decisiones Los objetos DataBoundGrid presentan el problema de que sólo actualizan la base de

datos a la que están asociados cuando cambian de registro, por lo que si el usuario pulsa el botón exportar sin haber cambiado de registro se perderán los cambios realizados en el mismo.

Con el evento LostFocus se provoca la actualización de la base de datos cuando el usuario cambia a otro control.

Flujograma Actualizar base de datos

Fin

IDEM para procedimientos:

DBG_EtiquetasBit

DBG _EtiquetasSalto

DBG _EtiquetasSubrutina

Page 157: DCSLLL

5 Programación

156

DBG _ComentariosBit

DBG _ComentariosDireccion

DBG _ComentariosLinea

Page 158: DCSLLL

5 Programación

157

5.8. Ventana de memoria interna (Frm_MDIChildMemoria)

Figura 53. Captura de la ventana de memoria interna

Ventana MDIchild.

Aparece a solicitud del usuario por medio del menú.

Ventana de visualización y edición de los valores que contienen las tablas internas que implementan el módulo de memoria de registros:

• Memoria de usuario: tablas de estados E/S y de registros.

• Memoria de sistema: tabla de estados del sistema.

Se utiliza un control de visualización (DataBoundGrid) para mostrar los datos de cada una de las tablas internas.

5.8.1. Documentación y decisiones

El mapeado de memoria se describe en el capítulo 3.1.2 Módulo de memoria de registros y las tablas que lo implementan en el capítulo 5.16 Módulo de soporte tablas internas (Mdl_TablasInternas).

Las tablas son:

• MemU_Usuario Implementa las zonas de memoria de usuario: Tabla de estados E/S y de registros.

• MemS_Sistema Implementa las zonas de memoria de sistema: Tabla de estados del sistema.

Como las dos tablas se componen de pocos campos y de poca longitud, se ha optado por situar los dos controles juntos, sin utilizar pestañas de selección.

Page 159: DCSLLL

5 Programación

158

Hay que tener en cuenta que la tabla que implementa la memoria de usuario decidió crearse de 0 a N, donde N es la dirección del último registro de 16 bits, para así obtener una alta velocidad de acceso al realizarse éste de forma directa (la posición M contiene la dirección M).

Sin embargo, dependiendo del modelo de LM la memoria de usuario puede presentar un salto desde que acaba la zona de estados E/S hasta que comienza la zona de registros, que debe de ser respetado a la hora de presentar el mapeado de memoria.

Es por ello, que a la hora de realizar la visualización, se requieren funciones que conviertan la posición del registro deseado en el control DBG, en la dirección (posición) de la tabla de memoria de usuario y a la inversa.

5.8.2. Variables globales Bool_FormCargado: Indica si se ha acabado el procedimiento “Load” que equivale a

que se haya acabado la carga del formulario.

Map_Memoria: Contiene el mapeado de memoria del sistema.

5.8.3. Procedimientos y funciones

5.8.3.1. Private Sub Form_Load() Inicializa el formulario, lo sitúa en posición y carga los datos de la tabla

correspondiente.

Flujograma Configura aspecto formulario desde el registro

Indica formulario cargado (Bool_FormCargado)

Refresca controles con los datos de la tabla interna (Sub_ActualizarDBGMemU)

Fin

5.8.3.2. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) Si es el usuario quien solicita descargar la ventana (botón ), se cancela descarga y

sólo se oculta para evitar cargar otra vez los datos la próxima vez.

Flujograma

Ha sido el usuario

Si Ocultar formulario

Indicar formulario oculto (Bool_MDIChildMemoriaVisible)

Actualizar información estado ventana en el menú (Sub_ActualizarMenu)

Cancelar la descarga

Fin

5.8.3.3. Private Sub Form_Unload(Cancel As Integer) Descarga la ventana guardando el aspecto de la ventana en el registro.

Guarda aspecto de la ventana en el registro

Indicar formulario descargado

Fin

Page 160: DCSLLL

5 Programación

159

5.8.3.4. Private Sub Form_Resize() Se hace que el control DataBoundGrid ocupe la máxima altura posible, en función del

tamaño del formulario, a no ser que se supere un tamaño mínimo.

No se modifica la anchura de los controles, pues los campos ya tienen la anchura correcta al dato que tienen que representar (0 a 65535).

Flujograma Altura formulario mayor o igual a alto mínimo

Si Calcular y aplicar altura a los DBG’s del formulario

Calcular y aplicar posición al resto de elementos

No Aplicar altura mínima a los DBG’s

Aplicar posición mínima al resto de elementos

5.8.3.5. Private Function Fun_HacerBookmark(Lng_Actual As Long) Convierte un entero a tipo string para utilizarlo como marcador (bookmark), variable

necesaria para el funcionamiento de los DataBoundGrid en modo Unbound.

Flujograma Convierte entero a string

Fin

5.8.3.6. Private Sub DBG_MemoriaUsuario_UnboundReadData(ByVal RowBuf As MSDBGrid.RowBuffer, StartLocation As Variant, ByVal ReadPriorRows As Boolean)

Rellena el objeto DBG_MemoriaUsuario con los datos de la tabla correspondiente MemU_Usuario.

Esta función aunque ha de ser programada por el usuario, debe de seguir las indicaciones de programación del control DataBoundGrid en modo Unbound. Es por ello que no se explica en detalle, si no que se indica la estructura básica.

De forma resumida el control indica una posición de inicio de lectura de registros, el número de registros deseados y si quiere los registros anteriores o posteriores a dicha posición.

Formulario El formulario ha sido cargado completamente

No Devuelve que no hay registros

Fin

Calcular número de registros del DBG en función del mapeado de memoria

El control solicita

Primer registro reg. de tabla interna (Fun_LeerRegistroMemoriaUsuario) (Fun_LeerRegistroMemoriaUsuario)

Devuelve el primer registro

Fin

Ultimo registro Lee reg. de tabla interna (Fun_LeerRegistroMemoriaUsuario)

Page 161: DCSLLL

5 Programación

160

Devuelve el último registro

Fin

Intermedios Lee reg. de tabla interna (Fun_LeerRegistroMemoriaUsuario)

Devuelve registros

Fin

Fin

IDEM para procedimiento:

DBG_MemoriaSistema_UnboundReadData

5.8.3.7. Private Sub DBG_MemoriaUsuario_UnboundWriteData(ByVal RowBuf As MSDBGrid.RowBuffer, WriteLocation As Variant)

Modifica en la tabla MemU_Usuario los cambios realizados en el control correspondiente DBG_MemoriaUsuario.

Como el control solo parametriza los valores modificados del registro editado, la función debe de rellenar los otros campos con los valores que ya tenía el registro en caso de existir.

Flujograma Obtener número de dirección modificada (Fun_MemUPosicionaDireccion)

Se ha modificado el valor de 1 bit de entrada

Si Valor de 1 bit dentro del rango (Fun_ValidarMemU1bit)

No Presentar aviso “Valor fuera de rango”

Abandonar el procedimiento

Si Escribir campo de 1 bit de entrada en memoria de usuario (Sub_EscribirRegistroMemUContenido1bE)

Se ha modificado el valor de 1 bit de salida

Si Valor de 1 bit dentro del rango (Fun_ValidarMemU1bit)

No Presentar aviso “Valor fuera de rango”

Abandonar el procedimiento

Si Escribir campo de 1 bit de salida en memoria de usuario (Sub_EscribirRegistroMemUContenido1bS)

Se ha modificado el valor de 16 bits

Si Valor de 16 bits dentro del rango (Fun_ValidarMemU1bit)

No Presentar aviso “Valor fuera de rango”

Abandonar el procedimiento

Si Escribir campo de 16 bits en memoria de usuario (Sub_EscribirRegistroMemUContenido16b)

Fin

IDEM para procedimiento:

Page 162: DCSLLL

5 Programación

161

DBG_MemoriaSistema_UnboundWriteData

5.8.3.8. Private Sub Txt_IraMemU_Change() Posiciona el DBG en la posición que corresponde a la dirección seleccionada.

Documentación y decisiones El control DBGrid presenta dos problemas de funcionamiento:

• Al introducir el número del último registro en el recuadro de texto, no se ha podido descubrir si por defecto del propio objeto o por un error no detectado en la programación del procedimiento DBG_MemoriaUsuario_UnboundReadData, el registro solicitado no se visualiza. Para solucionarlo se solicita el penúltimo registro y una vez visualizado, se selecciona el último.

• Una vez el DBGrid visualizaba el registro solicitado en el recuadro de texto, el primer cambio introducido en alguno de los campos no quedaba memorizado, tras realizar muchas pruebas se ha determinado que la solución era seleccionar otro registro momentáneamente.

Flujograma El texto corresponde a una dirección correcta (Fun_ DireccionMemUCorrecta)

Si Se solicita el último registro?

Si Cambiar a penúltimo registro

Obtener posición de la dirección (Fun_MemUDireccionaPosicion)

Situar DBG en la posición obtenida

Se solicitaba el último registro?

Si Seleccionar último registro

No Seleccionar momentánemamente otro registro

Fin

IDEM para procedimiento:

Txt_IraMemS_Change

5.8.3.9. Public Function Fun_MemUPosicionaDireccion(Int_Posicion As Integer) As Integer

Convierte la posición recibida del registro DBG, en la dirección que le corresponde de la memoria de usuario.

Flujograma Calcular dirección compensando el salto

Devolver dirección calculada

Fin

5.8.3.10. Public Function Fun_MemUDireccionaPosicion(Int_Direccion As Integer) As Integer

Convierte la dirección recibida de la memoria de usuario, en la posición del registro DBG que le corresponde.

Page 163: DCSLLL

5 Programación

162

Flujograma Calcular posición compensando el salto

Devolver posición calculada

Fin

5.8.3.11. Private Function Fun_ValidarMemU1bit(Str_Valores As String) As Boolean Valida el texto para que cumpla con el formato adecuado. Devuelve verdadero si el

valor está dentro del rango de 1 bit (0,1).

Flujograma El valor corresponde al rango (0 – 1)

Si Devolver verdadero

No Devolver falso

Fin

5.8.3.12. Private Function Fun_ValidarMemU16bit(Str_Valores As String) As Boolean Valida el texto para que cumpla con el formato adecuado. Devuelve verdadero si el

valor está dentro del rango de 16 bits sin signo (0 - 65535).

Flujograma El valor corresponde al rango (0 – 65535)

Si Devolver verdadero

No Devolver falso

Fin

5.8.3.13. Public Sub Sub_ActualizarDBGMemU() Refresca los datos del control DBG de memoria de usuario manteniendo la misma

dirección que estaba seleccionada, siempre que siga existiendo.

Flujograma Leer límites mapeado de memoria actual (Fun_LeerMapeadoMemoria)

Leer dirección actual

Refrescar control DBG

Obtener posición de la dirección anterior (Fun_MemUDireccionaPosicion)

Existe la dirección anterior

Si Situar DBG en la posición obtenida

Fin

5.8.3.14. Public Function Fun_MemSPosicionaDireccion(Int_Posicion As Integer) As Integer

No presenta las mismas dificultades que la memoria de usuario, pues la memoria de sistema no presenta discontinuidades. La única conversión necesaria es que la dirección 0 ocupa la posición 1.

Page 164: DCSLLL

5 Programación

163

Flujograma Calcular dirección: dirección = posición - 1

Devolver dirección calculada

Fin

5.8.3.15. Public Function Fun_MemSDireccionaPosicion(Int_Direccion As Integer) As Integer

Convierte la dirección recibida de la memoria de sistema, en la posición del registro DBG que le corresponde.

Flujograma Calcular posición: posición = dirección + 1

Devolver dirección calculada

Fin

5.8.3.16. Private Function Fun_ValidarMemS8bit(Str_Valores As String) As Boolean Valida el texto para que cumpla con el formato adecuado. Devuelve verdadero si el

valor está dentro del rango de 8 bits sin signo (0 - 256).

Flujograma El valor corresponde al rango (0 – 256)

Si Devolver verdadero

No Devolver falso

Fin

Page 165: DCSLLL

5 Programación

164

5.9. Ventana de programa (Frm_MDIChildPrograma)

Figura 54. Captura de la ventana de programa

Ventana MDIchild.

Aparece a solicitud del usuario por medio del menú.

Permite la visualización de las líneas de programa.

Mediante una barra de desplazamiento vertical, el usuario selecciona la primera línea a visualizar, completándose la pantalla con las líneas siguientes si las hubiese. Al seleccionar con el ratón un elemento de los que forman la línea, aparece un recuadro de texto con la información de los archivos de documentación relacionados:

• Línea: Comentario.

• Dirección: Comentario y etiqueta.

• Bit: Comentario y etiqueta.

• Salto: Etiqueta.

• Subrutina: Etiqueta.

Si se está depurando el programa ya sea línea a línea o ciclo a ciclo, una vez se acaba de ejecutar el comando en curso, permite al usuario observar la secuencia lógica y las operaciones realizadas. Para ello:

• Colorea en verde la secuencia lógica verdadera a lo largo de las formaciones serie o paralelo que forman la línea de programa.

• En elementos que trabajan con valores enteros: si el elemento es de entrada, presenta debajo del mismo el valor que tenía antes de realizar la operación; Si es de salida presenta el valor resultante de la operación.

Page 166: DCSLLL

5 Programación

165

Si se está realizando la simulación paso a paso por líneas, mediante una casilla de selección el usuario puede hacer que automáticamente se visualice la última línea ejecutada, o sólo refrescar las líneas en pantalla.

5.9.1. Documentación y decisiones

5.9.1.1. Separar las líneas Si se lee el capítulo 4.2 F2 – 620 Stand alone loader (*.ldr) se deduce que no hay forma

de obtener los códigos que corresponden a una línea, a no ser que se analicen todos los elementos precedentes identificando las líneas anteriores.

Si no se quiere perder tiempo evaluando los elementos anteriores a la hora de visualizar o simular una línea en cuestión, en la apertura del proyecto el fichero de programa *.ldr debe descomponerse en las partes que lo integran, y una vez identificada la parte que contiene el código de programa, separar y guardar las líneas de programa por separado.

5.9.1.2. Representación de las líneas El primer paso es determinar como se va a realizar la visualización de las líneas de

programa.

En el capítulo 4.2 F2 – 620 Stand alone loader (*.ldr) se detalla que cada línea de programa está formada por una matriz de máximo 5 filas x 10 columnas. Las 9 columnas primeras sirven para realizar las formaciones serie y/o paralelo de elementos de entrada. La última columna se reserva para introducir el elemento de salida deseado.

La captura superior muestra una de las celdas de la matriz de edición del programa MS-

DOS Loader. La celda se divide en tres partes: nombre de etiqueta de dirección, número de dirección y símbolo del comando. Presionando la tecla ? una vez, aparecen todos los campos de la etiqueta de la dirección seleccionada por el puntero, si se pulsa otra vez, aparece el texto del comentario asociado.

Composición de la tabla gráfica Para realizar la visualización de las líneas, se puede utilizar el formato de texto que usa

el MS-DOS Loader, o pasar a un formato gráfico.

Como Visual Basic permite trabajar fácilmente con gráficos y se necesita colorear la secuencia lógica verdadera, se va a utilizar el método gráfico. Dibujar una línea va a equivaler a montar un puzzle, cuyas piezas van a ser las imágenes que corresponden a los símbolos de cada una de las instrucciones del set de instrucciones.

Uno de los controles de Visual Basic que permite esto es el MSFlexGrid, que no es más que una tabla cuyas celdas pueden contener texto y/o imágenes.

Así, cada una de las partes que componen las celdas de MS-DOS Loader se va a representar utilizando:

• Símbolo: Imagen

• Nombre de etiqueta: Texto

• Número de dirección: Texto

Page 167: DCSLLL

5 Programación

166

• Texto completo de etiqueta y comentario: Cuadro de texto adicional que aparecerá cuando el usuario seleccione una de las celdas, y desaparecerá cuando pulse sobre el mismo.

Como cada imagen va a contener sólo el símbolo de la instrucción, existe la necesidad de disponer de imágenes de unión que contengan las líneas de interconexión para visualizar las formaciones serie o paralelo.

Además, como la ventana va a contener tantas líneas de programa como quepan, no existe la posibilidad de que en una parte de la ventana se informe del número de línea visualizado, tal y como ocurre en el MS-DOS Loader. Por ello, pudiendo elegir entre incluir esta información en una columna o una fila adicional para cada línea, se ha elegido la primera opción para no reducir el número de líneas a visualizar de una sola vez.

Así la matriz de 9x5 equivale a una matriz de 21x5.

Texto: Número de línea+Línea no ejecutada/saltada.1 click - Presenta información asociada: comentario de línea

Imagen: Símbolo de interconexión.

Imagen: Símbolo de instrucción.Texto: Etiqueta+Dirección+Valor entero si se está depurando1 click - Presenta información asociada: etiqueta y comentario de dirección/bit/salto/subrutina

0 1 2 20

0

4

Figura 55. Composición de la línea gráfica

Coloreando la secuencia lógica Si se quiere tener una imagen para representar cada una de las necesidades, la cantidad

de imágenes sería muy elevada, ya que se tienen que implementar las siguientes combinaciones:

• Símbolo de instrucción o símbolo de interconexión en lógica falsa.

• Símbolo de instrucción o símbolo de interconexión en lógica verdadera.

• Símbolo de instrucción forzado a OFF.

• Símbolo de instrucción forzado a ON.

Por ello, se ha decidido utilizar el control ImageList de VisualBasic para proporcionar las imágenes que necesita el control MSFlexGrid.

Este control es un almacén de imágenes. Su función “Overlay” superpone un mapa de bits sobre otro para crear una tercera imagen compuesta. La propiedad “MaskColor” determina que color de la imagen superpuesta es transparente.

Así, sólo se va a necesitar una imagen para cada símbolo de instrucción o interconexión y cuatro adicionales con cada uno de los colores que van a representar cada uno de los estados:

• Lógica falsa: NEGRO.

Page 168: DCSLLL

5 Programación

167

• Lógica verdadera: VERDE.

• Forzado a OFF: AZUL.

• Forzado a ON: ROJO.

5.9.1.3. Interpretación de las líneas Para facilitar la comprensión, se ha optado por que el formulario utilice las funciones

del módulo Mdl_InterpretarLineas, que será el que se encargue de decodificar los elementos de la línea de programa a visualizar.

Trabajar de esta forma hace más lento el proceso, pues implica guardar los datos a visualizar en un elemento intermedio a medida que la línea de programa es interpretada, y luego copiarlos en el objeto MSFlexGrid, en vez de trabajar directamente sobre el objeto.

De acuerdo a la Figura 55. Composición de la línea gráfica, el elemento intermedio debe de estar formado por:

• Número de filas ocupadas por la línea interpretada: Así copiar el elemento intermedio sobre el objeto gráfico se reduce a copiar 21xNFilas

• Tabla de registros (21 columnas x un máximo de 5 filas) cada uno compuesto de los siguientes campos, para poder contener toda la información necesaria:

• Imagen: Cadena de texto con la referencia de la imagen de símbolo a utilizar.

• Estado: Cadena de texto con la referencia de la imagen de color a utilizar.

• Texto: Cadena de texto a visualizar en la celda.

• Información: Cadena de texto a visualizar en el cuadro de texto que presenta los datos de los archivos de documentación.

5.9.1.4. Recuadro de texto de información El objeto gráfico MSFlexGrid, no permite almacenar una cadena de texto en cada una

de sus celdas donde guardar la información (comentario y etiqueta) a presentar cuando se seleccione la celda.

Por ello, se necesita implementar una matriz de cadenas de texto con las mismas dimensiones que el objeto MSFlexGrid. Cuando el módulo de interpretación de líneas devuelva el objeto intermedio, los campos “imagen”, “estado” y “texto” se escribirán sobre el objeto gráfico, mientras que el campo “información” incializará la matriz de información. De esta forma, al seleccionar una celda del objeto gráfico, el recuadro de texto accederá a la celda análoga de la matriz de información y presentará el contenido.

5.9.2. Variables globales Bool_FormCargado: Indica si se ha acabado el procedimiento “Load” que equivale a

que se haya acabado la carga del formulario.

Str_InformacionMSFG: Matriz que contiene la información a visualizar en cada una de las celdas que forman el objeto MSFG.

5.9.3. Procedimientos y funciones

5.9.3.1. Private Sub Form_Load() Inicializa el formulario y lo sitúa en posición.

Page 169: DCSLLL

5 Programación

168

Flujograma Configura aspecto formulario desde el registro

Configura comportamiento, dimensión, alto fila y ancho columna objeto MSFG

Configura objeto barra de desplazamiento vertical

Indica formulario cargado (Bool_FormCargado)

Fin

5.9.3.2. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) Si es el usuario quien solicita descargar la ventana (botón ), se cancela descarga y

sólo se oculta para evitar cargar otra vez los datos la próxima vez.

Flujograma Ha sido el usuario

Si Ocultar formulario

Indicar formulario oculto (Bool_MDIChildProgramaVisible)

Actualizar información estado ventana en el menú (Sub_ActualizarMenu)

Cancelar la descarga

Fin

5.9.3.3. Private Sub Form_Unload(Cancel As Integer) Descarga la ventana guardando el aspecto de la ventana en el registro.

Guarda aspecto de la ventana en el registro

Indicar formulario descargado (Bool_FormCargado)

Fin

5.9.3.4. Private Sub Form_Resize() Se hace que el control MSFlexGrid ocupe el máximo espacio posible de acuerdo al

tamaño de la ventana. Además se resitúan el resto de objetos a las nuevas dimensiones del objeto MSFlexGrid.

El objeto MSFG debe de ocupar la máxima altura posible, pues al aumentar la longitud del control aumenta el número de filas que caben en él, permitiendo visualizar más líneas de programa en la misma ventana. Sin embargo, se debe de respetar un alto mínimo para el cual el control no se adaptará.

Cada cambio en la longitud implica calcular el número de filas del objeto.

Igual se hace con el ancho del control MSFG, sin embargo en este caso el número de las columnas debe de permanecer constante. Es por ello que el control no se adaptará en caso de sobrepasar un ancho mínimo ni el ancho máximo necesario para representar todas las columnas.

Al incluir nuevas celdas es necesario aplicar la configuración de justificación del texto a cada una de ellas.

Flujograma

Ocultar objeto MSFG

Page 170: DCSLLL

5 Programación

169

Altura formulario mayor o igual a alto mínimo

Si Calcular y aplicar altura a los objetos MSFG

No Aplicar altura mínima a los objetos MSFG

Ancho formulario mayor a ancho máximo

Si Aplicar ancho máximo al objeto MSFG

No Ancho formulario menor a ancho mínimo

Si Aplicar ancho mínimo al objeto MSFG

No Calcular y aplicar ancho del objeto MSFG

Recalcular número de filas control MSFG

Aplicar número de filas matriz de información (Str_InformacionMSFG)

Justificar celdas de la columna cero a centro-centro

Justificar celdas del resto de columnas a arriba-centro

Calcular y aplicar posición de la barra de desplazamiento vertical

Calcular y aplicar posición objetos de selección de opciones de visualización

Calcular y aplicar posición cuadro de texto información del número de línea

Rellenar control MSFG con líneas de programa (Sub_RellenarMSFG)

Hacer visible objeto MSFG

Fin

5.9.3.5. Private Sub VS_Programa_Scroll() Si el usuario arrastra el marcador de la barra de desplazamiento vertical, se visualiza un

recuadro de texto informando del número de línea de destino en cada posición.

Flujograma Escribir línea de destino en el cuadro de texto

Hacer visible cuadro de texto

Fin

5.9.3.6. Private Sub VS_Programa_Change() Una vez el usuario ha seleccionado la nueva posición del marcador de la barra de

desplazamiento vertical, se debe de visualizar en la ventana la línea correspondiente.

Además ya no es necesario el cuadro de texto que informa de la línea de destino, por lo que se debe de ocultar.

Flujograma Escribir línea de destino en el cuadro de texto (Sub_RellenarMSFG)

Ocultar cuadro de texto de información de línea de destino

Fin

Page 171: DCSLLL

5 Programación

170

5.9.3.7. Public Sub Sub_PeticionRefresco() Procedimiento utilizado por la ventana principal para que una vez acabada la orden de

ejecución paso a paso, la ventana se actualice con los cambios reproducidos.

Documentación y decisiones Cuando se está realizando la simulación paso a paso por líneas, a veces resulta

conveniente que esta ventana de visualización automáticamente se sitúe en la última línea ejecutada, mientras que otras puede que el programador quiera observar los cambios que la ejecución produce en la misma línea.

Por ello, se añade una casilla de selección donde el usuario puede elegir entre actualización automática o no.

Flujograma Está seleccionada la opción de actualización automática

Si Leer última línea ejecutada (Fun_EstadoSimulacion)

Número de línea devuelto correcto?

Si Número de línea devuelto igual a línea visualizada actualmente?

Si Refrescar objeto MSFG (Sub_RellenarMSFG)

No Situar barra de desplazamiento en el número de línea devuelto

No Refrescar objeto MSFG (Sub_RellenarMSFG)

Fin

5.9.3.8. Private Sub Sub_RellenarMSFG() Rellena el objeto MSFlexGrid con las líneas de programa.

Documentación y decisiones Antes de realizar cambios en el objeto MSFlexGrid, lo mejor es ocultarlo, pues acelera

el procedimiento.

Flujograma

Ocultar objeto MSFlexGrid

Leer primera línea a visualizar

Rellenar matriz gráfica con las líneas de programa (Sub_RellenarMatrizGrafica)

Leer primera línea gráfica (Fun_LeerRegistroLineaDibujo)

Seleccionar primera fila del control MSFlexGrid

Seleccionar primera columna del control MSFlexGrid

Seleccionar celda con la fila y columna actuales

Escribir texto

Ha sido inicializada la imagen?

No Seleccionar imagen en blanco

Ha sido inicializado el estado lógico?

No Seleccionar estado falso

Page 172: DCSLLL

5 Programación

171

Escribir imagen combinada de imagen y estado lógico

Rellenar matriz de cadenas de información

… Repetir hasta rellenar la última columna

Se han acabado las filas de la línea gráfica actual?

Si Última línea de programa?

Si Seleccionar imagen en blanco

No Leer siguiente línea gráfica (Fun_LeerRegistroLineaDibujo)

… Repetir hasta rellenar la última fila del objeto MSFlexGrid

Se calcula el número de líneas que saltan los botones “Re Pag” y “Av Pag”

Hacer visible objeto MSFlexGrid

Fin

5.9.3.9. Private Sub MSFG_Programa_Click() Si el usuario selecciona una celda, este procedimiento se encarga de presentar un

recuadro de texto con la información de etiqueta y comentario que le corresponde.

Flujograma Situar cuadro de texto en la posición que le corresponde a la celda seleccionada

Escribir texto de información en el cuadro de texto

Hacer visible cuadro de texto

Fin

5.9.3.10. Private Sub Txt_Informacion_Click() Pulsar sobre el cuadro de texto, significa que el usuario desea ocultar el cuadro de texto

de información.

Flujograma

Ocultar cuadro de texto

Fin

Page 173: DCSLLL

5 Programación

172

5.10. Ventana de simulación (Frm_MDIChildSimulacion)

Figura 56. Captura de la ventana de simulación

Ventana MDIchild.

Aparece a solicitud del usuario por medio del menú.

La parte superior de esta ventana, permite editar los parámetros de configuración de la simulación, disponiendo de un botón para validar los datos y otro para cancelar cambios y recuperar los parámetros guardados:

• Líneas a simular.

• Tiempo estimado de la duración de ejecución de un ciclo (µs).

• Tiempo total de simulación (µs).

• Número total de ciclos a simular.

La parte central, permite configurar la evolución de las direcciones:

• Editar las expresiones de evolución deseada de las direcciones de la tabla de estados E/S y de la tabla de registros.

• Seleccionar las direcciones de 1 bit de las que guardar la evolución a lo largo de la simulación.

La parte inferior, permite visualizar la evolución de las direcciones:

Page 174: DCSLLL

5 Programación

173

• Cronograma donde se visualiza la evolución a lo largo de la simulación de las direcciones de 1 bit seleccionadas.

• Parámetros de configuración del cronograma: tiempo de inicio, tiempo de fin y configuración del grid vertical automático o manual.

5.10.1. Documentación y decisiones

5.10.1.1. Parámetros de simulación

Tiempo de ejecución Para poder realizar una simulación correcta, sobretodo al simular temporizadores, es

necesario que la simulación esté basada en la evolución temporal de los valores de las direcciones.

Así los parámetros necesarios para realizar la simulación, serán principalmente:

• Tiempo de la duración de ejecución de un ciclo.

• Tiempo total de simulación.

En algunos casos, el usuario puede preferir indicar el número de ciclos. Por lo que para un determinado tiempo de ciclo, el valor del parámetro tiempo total de simulación dependerá del valor del parámetro número de ciclos, y a la inversa, de acuerdo a la siguiente fórmula:

Tiempo total = Tiempo de ciclo x Número de ciclos

Tal y como se puede observar en las tablas del apartado 3.3 Ciclo de ejecución de programa lógico (Ciclo de scan), en algunos casos el tiempo de ejecución de una instrucción puede variar, sin que en ningún sitio de la documentación consultada se expliquen los motivos.

Por esta razón, se ha desestimado que fuese el simulador quien calculase el tiempo de ejecución de un scan de programa en función de las instrucciones que lo componen, siendo el usuario quien debe introducir este valor ya sea extrayéndolo de la línea de información de la pantalla del MS-DOS Loader cuando el LM ejecuta el programa, o por estimación.

En la misma tabla se aprecia, que los tiempos de ejecución de cada instrucción son del orden de pocos microsegundos, por lo que se va a utilizar esta unidad para trabajar con una resolución que permita seguir la evolución de los valores de las direcciones a lo largo de las líneas.

Líneas a ejecutar En ciertas ocasiones puede interesar no ejecutar todo el programa, por ejemplo, cuando

se intente evaluar un programa de muchas líneas y sólo nos interesen las líneas de programa destinadas a un proceso determinado.

Para que el usuario especifique las líneas que desea ejecutar, se va a utilizar el formato habitual de selección de páginas en las ventanas de impresión de cualquier programa de Windows:

• Selección de líneas sueltas: “1,2,6” implica ejecutar líneas 1, 2 y 6.

• Selección de rangos de líneas: “1-3” implica ejecutar líneas 1, 2 y 3.

• Combinación de ambos estilos: “1,2,4-6,9” implica ejecutar líneas 1,2,4,5,6 y 9.

Page 175: DCSLLL

5 Programación

174

Guardando los parámetros Para poder restaurar los datos, es necesario guardar una copia de los mismos antes de la

modificación.

Sin embargo, hay que tener en cuenta que estos datos son utilizados por el módulo de simulación (Mdl_Simular), así que será suficiente con crear en el mismo dos funciones. La primera, ejecutada por el botón de validar, escribirá los parámetros con los valores de los recuadros de texto. La segunda, ejecutada por el botón de restaurar, leerá los parámetros y los escribirá en los recuadros de texto.

5.10.1.2. Evolución de las direcciones

Introducción de las expresiones de evolución de las entradas En el apartado 3.1 Mapeado de memoria, se describen las tablas que componen el

módulo de memoria de registros.

• Tabla de estados de E/S

• Tabla de registros

• Tabla de estados del sistema

La siguiente figura resume que elementos pueden escribir en las tablas de memoria de usuario (tabla de estados E/S y tabla de registros), y el momento en que lo hacen:

1 BITENT .

T ABLA DEEST ADOS E/S(E/S FISICAS)

T ABLA DEEST ADOS E/S

(BOBINASINT ERNAS)

T ABLA DEREGIST ROS

1 BITSAL. 16 BIT S

Al comienzo de cada ciclo o al ejecutarla instrucción ISS, se copian los valores

de las tarjetas de entradas

La ejecución de una instrucción PULLlee el valor de la dirección de la tarjeta de

entrada en ese instante

El procesador lógico escribe losresultados de las salidas en la direccióncorrespondiente en el instante en que

ejecuta la línea de programa

El LMM escribe los valores recibidosdesde el sistema de control distribuidoen la dirección correspondiente con

ciclos de 1/2 o 1 seg.

Figura 57. Modificación de los valores de las tablas de memoria de usuario

Puesto que no es un objetivo del proyecto simular el LM con el ordenador trabajando conectado a la periferia de tarjetas de entradas físicas, ni con el sistema de control distribuido, para poder realizar una simulación es necesario que el usuario pueda introducir los cambios que producirían en los registros ambos elementos.

No es necesario poder especificar la evolución de los registros de la tabla de estados del sistema pues esta tabla sólo puede ser modificada por el procesador del LM.

Page 176: DCSLLL

5 Programación

175

Cuando se está trabajando con los registros binarios de la zona de E/S físicas, el valor leído por el procesador es el resultado de sumar los valores que contienen la tabla de entradas y la de salidas, por ello, es necesario que el usuario pueda especificar la evolución de ambas tablas por separado para no sobrescribir el valor de la dirección física de entrada, con el resultado de la ejecución de una línea de programa con un elemento de salida con la misma dirección.

Así es necesario poder introducir expresiones de evolución para las siguientes tablas:

• Tabla de estados de entrada de 1 bit (de 0 a un máximo de 2047).

• Tabla de estados de salida de 1 bit (de 0 a un máximo de 8191).

• Tabla de estados de entrada de 16 bits correspondientes a tarjetas analógicas (de 0 a un máx. de 2047).

• Tabla de registros de 16 bits (de 4096 a un máximo de 8191).

Como las dos últimas tablas tienen rangos de direcciones distintos, se van a agrupar en una sola.

Para que el usuario indique que nuevo valor tomará el registro en cada uno de los momentos deseados, se va a seguir un método similar al de selección de líneas en el apartado anterior. Así, la evolución de cierto registro se realizará por medio de una secuencia de grupos (Tiempo en microsegundo, Valor) separados por puntos y coma:

Dirección: Tiempo, Valor; Tiempo, Valor; …

Tiempo: Momento de cambio expresado en microsegundos.

Valor para registros de 1 bit: 0, 1.

Valor para registros de 16 bits: 0-65535.

Guardando las expresiones de evolución de las entradas

Una solución para guardar estas cadenas es utilizar la propia tabla de memoria de usuario, sin embargo, el mayor tamaño de los registros haría más lento el acceso (problema crítico en modo simulación), por lo que se va a crear una nueva tabla.

Como la evaluación de la evolución de las direcciones se va a realizar al comienzo de cada ciclo, excepto en el caso de direcciones de entradas analógicas (instrucción PULL), y accediendo a los registros consecutiva y no aletoriamente, en vez de usarse memoria interna se va a crear la tabla en la base de datos, de esta forma el usuario podrá editar las expresiones de evolución de forma externa al programa, con la función de exportación del formulario de documentación (ver capítulo 5.17 Módulo de soporte para bases de datos (Mdl_BasesdeDatos)).

Para facilitar la selección del registro a utilizar (hay que tener en cuenta que pueden existir 8192) se va añadir un recuadro de texto en el que el usuario podrá escribir el número de dirección deseada.

También se considera oportuno que el usuario pueda seleccionar entre visualizar todos los registros, o sólo aquellos que tengan expresiones de evolución.

Seguimiento de la evolución de las salidas

En vez de guardar la evolución de todas las direcciones de la memoria de usuario para poder luego representar su evolución, se ha decidido:

Page 177: DCSLLL

5 Programación

176

• No guardar la evolución de los registros de 16 bits, ya que su representación sería complicada y poco útil.

• Guardar la evolución de los registros de 1 bit que el usuario seleccione, para así reducir la memoria que se necesitaría si se quisiese guardar la evolución de todos ellos, cuando en la mayoría de los casos no sería consultada.

A diferencia del punto anterior, en el caso de las salidas no es necesario guardar la evolución de la tabla de entradas y salidas de 1 bit por separado, al ser el valor leído en cada dirección la suma del valor contenido en ambas tablas.

Por lo que es suficiente implementar una lista en la que el usuario pueda seleccionar las direcciones de las que hacer el seguimiento.

Para poder trabajar con la lista se ha pensado en utilizar cuatro botones que realicen las siguientes funciones:

• Añadir a la lista la dirección del registro seleccionado en la tabla de expresiones de evolución.

• Eliminar la dirección seleccionada en la lista.

• Reordenar subiendo una posición la dirección seleccionada. Hay que tener en cuenta que la representación se va a realizar en el orden en que estén listadas.

• Reordenar bajando una posición.

Guardando la evolución de las salidas Por la misma razón que con las evoluciones de las entradas, no se va a añadir un campo

adicional a los registros de memoria de usuario donde guardar la evolución de las salidas. Sin embargo, a diferencia de las entradas en que la evaluación se realiza una vez al comienzo del ciclo, las salidas pueden modificarse con la ejecución de cada nueva línea, por lo que para no perjudicar la velocidad de simulación, se va a utilizar una tabla en memoria interna.

Así, la evolución de cada salida se va a guardar en una tabla de registros donde cada registro está compuesto por dos campos: Tiempo en microsegundos (“Tiempo”) y el valor a partir del momento indicado “Valor”.

Para ahorrar memoria:

• La tabla de direcciones sólo se va a crear con aquellas direcciones seleccionadas por el usuario en la ventana de simulación.

• Sólo se debe de guardar el nuevo registro, si su campo “Valor” es diferente al del último guardado.

Para acelerar la escritura de los nuevos grupos (tiempo,valor), se van a añadir dos nuevos campos a los registros de memoria de usuario:

• “GuardarEvolucion”: Informa al programa de si se debe de guardar la evolución de la dirección actual en el mismo aceso que se realiza para actualizar su contenido con el resultado de la ejecución de la línea.

• “IndiceEvolucion”: Contiene el índice del registro de la tabla de evolución de salidas que corresponde a la dirección del registro de memoria de usuario.

Page 178: DCSLLL

5 Programación

177

5.10.1.3. Cronograma Ya se ha decidido que el cronograma va a representar las direcciones seleccionadas en

la lista anterior y respetando el orden en que aparecen.

Así como la representación vertical (líneas horizontales) no representa ningún problema, pues los valores a representar son 0 ó 1, la representación horizontal es más complicada pues debe de tener en cuenta el tiempo en que se cambia de estado.

Se ha decidido que el usuario pueda seleccionar el intervalo de simulación que le interese visualizar, para lo que necesita poder definir:

• Tiempo de inicio en microsegundos

• Tiempo de fin en microsegundos

Además es necesario representar divisiones verticales con las que el usuario pueda determinar el momento en que se ha producido el cambio de estado, para ello, el usuario va a poder seleccionar entre divisiones manuales o automáticas:

• Divisiones manuales: Permite seleccionar el intervalo de tiempo entre cada división.

• Divisiones automáticas: El propio programa decide las divisiones verticales más adecuadas a representar para el intervalo seleccionado.

Objetos de Visual Basic Para representar gráficos, se utiliza el objeto “PictureBox”, que permite dibujar líneas y

escribir texto en la posición deseada.

En el caso de que no todas las direcciones seleccionadas quepan en la ventana, para poder moverse a lo largo de la misma, el objeto PictureBox trabaja conjuntamente con una barra de desplazamiento vertical “VScrollBar”.

5.10.2. Procedimientos y funciones comunes al formulario

5.10.2.1. Private Sub Form_Load() Inicializa el formulario y lo sitúa en posición.

Flujograma

Configura aspecto formulario desde el registro

Configura comportamiento, dimensión, alto fila y ancho columna objeto MSFG

Configura objeto barra de desplazamiento vertical

Indica formulario cargado (Bool_FormCargado)

Fin

5.10.2.2. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)

Si es el usuario quien solicita descargar la ventana (botón ), se cancela descarga y sólo se oculta para evitar cargar otra vez los datos la próxima vez.

Flujograma Ha sido el usuario

Si Ocultar formulario

Indicar formulario oculto (Bool_MDIChildSimulacionVisible)

Page 179: DCSLLL

5 Programación

178

Actualizar información estado ventana en el menú (Sub_ActualizarMenu)

Cancelar la descarga

Fin

5.10.2.3. Private Sub Form_Unload(Cancel As Integer) Descarga la ventana guardando el aspecto de la ventana en el registro.

Flujograma Guarda aspecto de la ventana en el registro

Indicar formulario descargado (Bool_FormCargado)

Fin

5.10.2.4. Private Sub Form_Resize() Si la ventana se hace más alta, se hace que el control PictureBox que alberga el

cronograma ocupe el máximo espacio posible de acuerdo al tamaño de la ventana. Esto implica mover los elementos situados por debajo para mantener la apariencia.

En el caso de cambiar el ancho, no sólo aumenta el objeto PictureBox, sino también el control MSFlexGrid para facilitar la visualización de la cadena de caracteres que describe la evolución de los registros.

Los valores de anchura y altura se adaptaran mientras no impliquen sobrepasar un tamaño mínimo, para el cual los controles permanecerán constantes para mantener la coherencia.

Flujograma Está cargado el formulario?

No Abandonar procedimiento

Altura formulario mayor o igual a alto mínimo

Si Calcular y aplicar altura a objeto PictureBox

Calcular y aplicar posición de objetos inferiores al PictureBox

No Aplicar altura mínima al objeto PictureBox

Aplicar posición mínima a objetos inferiores al PictureBox

Aplicar valores calculados al resto de objetos implicados

Ancho formulario mayor o igual a ancho mínimo

Si Calcular y aplicar altura a objeto PictureBox

No Aplicar ancho mínimo a objeto PictureBox

Redibujar cronograma. (Sub_ActualizarGrafico)

Fin

5.10.3. Procedimientos y funciones de la sección “Parámetros de simulación”

5.10.3.1. Private Sub Txt_TiempoCiclo_Validate(Cancel As Boolean) Si el usuario cambia el tiempo estimado de duración de un ciclo, se modifica el

parámetro con el número total de ciclos de acuerdo a la fórmula:

Page 180: DCSLLL

5 Programación

179

Número de ciclos = Tiempo total / Tiempo de ciclo

Por ser el cociente de una división, sólo se permite la operación si el texto introducido es numérico y distinto de cero.

5.10.3.2. Private Sub Txt_TiempoTotal_Validate(Cancel As Boolean) Si el usuario cambia el tiempo total de ejecución, se modifica el parámetro con el

número total de ciclos de acuerdo a la fórmula:

Número de ciclos = Tiempo total / Tiempo de ciclo

Sólo se permite la operación si el tiempo estimado de duración de un ciclo es numérico y distinto de cero.

5.10.3.3. Private Sub Txt_NumeroTotalCiclos_Validate(Cancel As Boolean) Si el usuario cambia el número de ciclos a ejecutar, se modifica el parámetro con el

tiempo total de ejecución de acuerdo a la fórmula:

Tiempo total = Tiempo de ciclo x Número de ciclos

Sólo se permite la operación si el número total de ciclos corresponde a un número.

5.10.3.4. Private Sub Txt_LineasaSimular_Validate(Cancel As Boolean) Si el usuario cambia las líneas a ejecutar se comprueba que son correctas.

5.10.3.5. Private Sub Cmd_Aplicar_Click() Si el usuario aprieta el botón de aplicar cambios, los elementos afectados son:

• En el módulo de simulación se actualizan los parámetros que configuran la simulación.

• En el módulo de tablas internas, se marcan todas las direcciones de las que habrá que guardar la evolución durante la ejecución.

Flujograma Escribir parámetros de simulación (Sub_EscribirConfiguracionSimulacion)

Marcar direcciones (Sub_MarcarDireccionesConSeguimientoEvolucion)

Fin

5.10.3.6. Private Sub Cmd_Restaurar_Click() Se restauran los parámetros que configuran la simulación, a partir de los valores del

módulo de simulación.

Flujograma Leer parámetros de simulación (Fun_EstadoSimulacion)

Copiar valores sobre los cuadros de texto

Fin

5.10.3.7. Private Function Fun_RangoLineasCorrecto() As Boolean Se comprueba si las líneas seleccionadas por el usuario, introducidas con el formato

especificado, existen (forman parte del programa).

#, #-#,#,#

Si no se especifica ninguna línea, se tienen que ejecutar todas las líneas.

Page 181: DCSLLL

5 Programación

180

Flujograma Mientras no final de texto o carácter igual a “,” o “-“

Leer siguiente carácter

Se actúa en función del último carácter

final de texto o “,” Existe la línea en el programa?

Si Repetir desde el principio

No Abandonar procedimiento indicando error

“-” Se considera número actual límite inferior del rango y se busca límite el superior.

… Se repiten los pasos del principio para localizar límite superior

Existen las líneas en el programa?

Si Repetir desde el principio

No Abandonar procedimiento indicando error

Devolver indicando si el texto es correcto o no

Fin

5.10.4. Procedimientos y funciones de la sección “Evolución de las direcciones”

5.10.4.1. Private Sub Sub_ConectarFrmEvolucion() Conecta el control Data del formulario a la tabla “Evolucion” de la base de datos

temporal, para actualizar el control DBGrid permitiendo introducir nuevas expresiones de evolución o editar existentes.

5.10.4.2. Public Sub Sub_ActualizarDBGEvolucion() Fuerza la actualización del objeto DBGrid.

5.10.4.3. Private Sub Txt_Ira_Change()

Si el usuario intenta acceder rápidamente a un registro introduciendo el número de la dirección en el recuadro de texto destinado para ese fin, si este existe, es mostrado en el control.

Busca en el control Data el texto introducido en el campo número de dirección de la tabla, por lo que el objeto DBGrid se sitúa en el registro coincidente.

5.10.4.4. Private Sub Chk_Todas_Click() Para que el usuario pueda seleccionar entre visualizar todos los registros o sólo los que

contienen expresiones de evolución, es suficiente chequear o no una casilla de selección.

Al trabajar con el control Data que permite acceder a la tabla utilizando sentencias SQL, implementar está función consiste en cambia el filtro de consulta.

5.10.4.5. Private Sub DBG_Evolucion_BeforeUpdate(Cancel As Integer) No se puede permitir guardar los cambios si las expresiones introducidas son

incorrectas.

Page 182: DCSLLL

5 Programación

181

Una celda en blanco, no es aceptada por el objeto DBGrid, por lo que en caso de que el usuario borre los datos de una celda, el programa automáticamente avisa de que sea sustituido por un espacio.

Una vez comprobado esto, sólo queda comprobar si la expresión introducida ya sea para direcciones de un bit o de 16 bits, es correcta, por medio de las funciones adecuadas.

5.10.4.6. Private Sub DBG_Evolucion_LostFocus() La actualización de los datos modificados en un registro de un control DBGrid sólo se

produce cuando se cambia de registro.

Antes de pasar el enfoque a otro control, fuerza la actualización de los datos que se estaban editando en ese momento para no perderlos a la hora de exportar la base de datos.

5.10.4.7. Private Function Fun_ValidarExpresionEvolucion1bit(ByVal Str_Valores As String) As Boolean

Se valida la expresión de evolución introducida para que cumpla con el formato adecuado.

Tiempo, Valor; Tiempo, Valor; …

Dónde el parámetro valor sólo puede contener valores 0 ó 1.

Si la cadena de texto es un espacio en blanco, se considera expresión de evolución vacía, pues el control DBGrid no acepta campos vacíos.

5.10.4.8. Private Function Fun_ValidarExpresionEvolucion16bit(ByVal Str_Valores As String) As Boolean

Se valida la expresión de evolución introducida para que cumpla con el formato adecuado.

Tiempo, Valor; Tiempo, Valor; …

Dónde el parámetro valor sólo puede contener valores dentro del rango 0-65535, límites incluidos.

Si la cadena de texto es un espacio en blanco, se considera expresión de evolución vacía, pues el control DBGrid no acepta campos vacíos.

5.10.4.9. Private Sub Cmd_AgregarDireccion_Click() Si el usuario presiona el botón “►”, se añade la dirección seleccionada en el control

DBGrid a la lista de direcciones.

Para facilitar la introducción de una lista ordenada, la nueva dirección se añadirá a la lista en la posición siguiente a la que estaba seleccionada, pasando a ser la dirección seleccionada en la lista.

5.10.4.10. Private Sub Cmd_QuitarDireccion_Click() Si el usuario presiona el botón “◄”, se elimina la dirección seleccionada en la lista, de

la lista. La dirección superior pasa a ser la dirección seleccionada.

5.10.4.11. Private Sub Cmd_SubirNivelDireccion_Click() Si el usuario presiona el botón “▲”, la dirección seleccionada en la lista, intercambia la

posición con la dirección anterior, permitiendo así reordenar la lista.

Page 183: DCSLLL

5 Programación

182

5.10.4.12. Private Sub Cmd_BajarNivelDireccion_Click() Si el usuario presiona el botón “▼”, la dirección seleccionada en la lista, intercambia la

posición con la dirección anterior, permitiendo así reordenar la lista.

5.10.4.13. Public Sub Sub_MarcarDireccionesConSeguimientoEvolucion() Marca en la tabla de memoria de usuario las direcciones seleccionadas en la lista de las

se tiene que guardar la evolución

5.10.4.14. Public Sub Sub_AñadirDireccionConSeguimientoEvolucion(Int_NDireccion As Integer)

Cuando se abre un proyecto, entre los archivos asociados se abre el archivo que contiene los datos del entorno de simulación, para ser restaurados.

A medida que se leen las direcciones, esta función permite añadirlas en la lista en la última posición, para así respetar el orden que tenían cuando se guardó el proyecto anteriormente.

5.10.4.15. Public Function Fun_LeerListaDirSeguimientoEvolucion () As VB.ListBox Cuando se abre un proyecto, entre los archivos asociados se guarda el archivo que

contiene los datos del entorno de simulación, para ser guardados.

Esta función devuelve el contenido del control Listbox (lista de direcciones de las que guardar la evolución), para que el módulo Mdl_Proyecto pueda escribirlas en el fichero de entorno de simulación, cuando se está cerrando el proyecto.

Ver capítulo 5.13.1.1 Codificación y estructura básica del fichero *.slm (entorno de simulación).

5.10.5. Procedimientos y funciones de la sección “Cronograma”

5.10.5.1. Private Sub Cmd_RefrescarCronograma_Click( Si el usuario presiona el botón “Refrescar”, se redibuja el cronograma de acuerdo a los

parámetros introducidos.

Únicamente es necesario llamar al prcedimiento “Sub_actualizarGrafico”.

5.10.5.2. Private Sub VS_Cronogramas_Change()Private Sub Si el usuario mueve la barra de desplazamiento vertical, se entiende que solicita cambiar

las direcciones representadas, por lo que se refresca el cronograma.

Únicamente es necesario llamar al procedimiento “Sub_actualizarGrafico”.

5.10.5.3. Public Sub Sub_ActualizarGrafico()

Redibuja el cronograma de la ventana gráfica teniendo en cuenta la posición seleccionada en la barra de desplazamiento vertical.

Flujograma Dibujar eje de coordenadas x

Dibujar eje de coordenadas y (tiempo de inicio)

Dibujar eje de coordenadas y (tiempo de fin)

Dibujar divisiones verticales para tiempos intermedios (Sub_DibujarGridVertical)

Dibujar divisiones horizontales para señales (Sub_DibujarGridHorizontal)

Page 184: DCSLLL

5 Programación

183

Dibujar señales (Sub_DibujarSeñales)

Fin

5.10.5.4. Private Sub Sub_ActualizarVSCronogramas() Al añadir o quitar una dirección de la lista de señales o cambiar el tamaño del

formulario, se llama a esta función para actualizar la barra de desplazamiento vertical para que el usuario pueda seleccionar todas las señales existentes.

Si las señales caben en una sola pantalla se deshabilita la barra de desplazamiento.

Si no caben en una sola pantalla se dimensiona el cursor para permitir la selección.

5.10.5.5. Private Sub Sub_DibujarGridVertical() Tal y como se definió al principio, en caso de que el usuario haya seleccionado grid

vertical manual, las líneas se dibujan de acuerdo a las preferencias del usuario.

Si se ha seleccionado modo automático, el programa decide las divisiones a dibujar.

Se entiende que como los cronogramas se utilizan para controlar la evolución de las direcciones a lo largo de varios ciclos, es mejor que el tiempo entre divisiones siempre sea un múltiplo del tiempo de ciclo.

Como además la ventana es pequeña, para no saturarla, se mantendrán las divisiones por debajo de 20.

Flujograma El flujograma del cálculo automático corresponde a:

Número de divisiones = número de ciclos que caben en el tiempo a representar

Número de divisiones mayor de 20?

Sí Incrementar n.

Tiempo entre divisiones = n x T

… Repetir hasta que número de ciclos menor de 20

Fin

5.10.5.6. Private Sub Sub_DibujarGridHorizontal() Dibujar el grid horizontal es más sencillo, pues las líneas se equiespacian una distancia

fija, suficiente para representar la evolución de la señal.

5.10.5.7. Private Sub Sub_DibujarSeñales()

Este procedimiento gestiona la representación de las señales, básicamente selecciona la siguiente dirección a visualizar, la posición vertical que le corresponde en la ventana y llama a la función Sub_DibujarSeñal para que la represente.

Hay que tener en cuenta que las direcciones se deben de visualizar en el mismo orden en que están listadas.

Si caben todas las señales en pantalla, comienza representando la última de la lista en la parte inferior y va subiendo hasta alcanzar la primera señal. Si no caben todas, determina la primera señal a representar en función de la posición de la barra desplazadora y calcula la última señal sumando el número de señales máximas que caben en la pantalla, para así realizar el procedimiento anterior.

Page 185: DCSLLL

5 Programación

184

5.10.5.8. Private Sub Sub_DibujarSeñal(Int_Direccion As Integer, Int_YBase As Integer)

Dibuja la evolución de la dirección recibida en la posición vertical indicada.

Tal y como se ha decidido anteriormente, la evolución de cada una de las direcciones de salida está almacenada en el registro de una tabla. Cada uno de estos registros es a su vez, una tabla de registros de dos campos: Tiempo en microsegundos y el valor a partir del momento indicado.

El control PictureBox, para dibujar entidades gráficas, no entiende de tiempos, sino de coordenadas (X, Y), por lo que se usa la función auxiliar (Fun_CoordenadaXSegunTiempo) para convertir el tiempo dado, en la coordenada X correspondiente. Esta función tiene en cuenta en que coordenada X se encuentra el eje de coordenadas Y (tiempo de inicio) y cuantas unidades de medida corresponden a un microsegundo.

Flujograma Escribir número de la dirección en eje vertical

Leer registro con la evolución de la dir. (Fun_LeerRegistroSalidaEjecucion1b)

Existe evolución para esta dirección?

No Escribir aviso de falta de evolución en lugar del cronograma

Abandonar el procedimiento

Repetir para todos los binomios hasta obtener indicación de fin (Bool_Salir)

Tiempo del binomio anterior < Tiempo de inicio < Tiempo del binomio actual

Si Comenzar línea horizontal en tiempo de inicio

Tiempo del binomio anterior < Tiempo de fin < Tiempo del binomio actual

Si Acabar línea horizontal en tiempo de fin

Indicar final del bucle (Bool_Salir)

Dibujar línea horizontal con el valor anterior

Tiempo de inicio < Tiempo actual < Tiempo de fin

Si Dibujar línea vertical en tiempo actual de valor anterior al actual

Leer siguiente binomio

No hay más binomios?

Si Dibujar línea horizontal con el último valor hasta el tiempo de fin

Indicar final del bucle (Bool_Salir)

… Repetir bucle

Fin

Page 186: DCSLLL

5 Programación

185

5.11. Ventana de selección de ficheros (Frm_ModalSeleccionFicheros)

5.11.1. Características

5.11.1.1. Descripción

Figura 58. Captura de la ventana de selección de ficheros

Ventana modal.

Permite al usuario seleccionar los archivos de soporte que quiere guardar.

Si el usuario pulsa aceptar, se guardan los archivos seleccionados. Si se pulsa cancelar se cierra el formulario sin guardar nada.

5.11.2. Documentación y decisiones Los archivos que deben poder ser guardados son todos aquellos que contienen datos que

pueden ser editados en el programa.

Tal y como ya se ha detallado en los capítulos anteriores son:

• Fichero de configuración *.cfg

• Ficheros de documentación:

*.lbl - Address_label – Etiquetas de direcciones

*.ace - Address_comment – Comentarios de direcciones

*.lce - Line_comment - Comentarios de líneas de programa

*.skp - Skip_label – Etiquetas de líneas de salto

*.jsr - Subroutine_label – Etiquetas de líneas de subrutina

*.bce - Bit_Comment – Comentarios de bit

*.blb - Bit_label – Etiquetas de bit

Además de estos archivos que son creados por el programa MS-DOS Loader, se va a crear un nuevo archivo *.slm para guardar el entorno de simulación (parámetros de simulación, evolución de las direcciones de entrada y direcciones de las que seguir la evolución), en vista del tiempo que necesita su configuración.

Page 187: DCSLLL

5 Programación

186

5.11.3. Procedimientos y funciones

5.11.3.1. Private Sub Cmd_Aceptar_Click() Guarda los ficheros seleccionados a partir de los datos de las tablas internas.

Se ha seleccionado guardar el fichero etiquetas dirección

Si Escribir archivo etiquetas dirección (Sub_EscribirFicheroEtiquetasDireccion)

IDEM para ficheros:

Etiquetas Bit (Sub_EscribirFicheroEtiquetasBit)

Etiquetas Salto (Sub_EscribirFicheroEtiquetasSalto)

Etiquetas Subrutina (Sub_EscribirFicheroEtiquetasSubrutina)

Comentarios Bit (Sub_EscribirFicheroComentariosDireccion)

Comentarios Dirección (Sub_EscribirFicheroComentariosBit)

Comentarios Línea (Sub_EscribirFicheroComentariosLinea)

Configuración (Sub_EscribirFicheroConfiguracion)

Entorno de simulación (Sub_EscribirFicheroEntornoSimulacion)

Descarga el formulario

Fin

5.11.3.2. Private Sub Cmd_Cancelar_Click() Descarga el formulario sin guardar archivos.

Descarga el formulario

Fin

Page 188: DCSLLL

5 Programación

187

5.12. Módulo de soporte general (Mdl_General) Librería de procedimientos.

Contiene los procedimientos usados por el resto de formularios y módulos de forma general.

5.12.1. Documentación y decisiones

5.12.1.1. Tratamiento de errores Hay que tener en cuenta que al programar mediante procedimientos que se llaman unos

a otros, tiene que implementarse un medio que permita transmitir los errores encontrados al siguiente procedimiento.

En vez de utlizar funciones que devuelvan el código de error, o procedimientos con parámetros pasados por referencia, se ha decidido utilizar una variable compleja global donde escribir los códigos de error. Los campos necesarios son:

• Existe: Indica si existe un error.

• Descripción: Contiene el texto que describe el error producido.

5.12.2. Variables globales Fal_Fallo: Variable compleja que controla los errores producidos.

5.12.3. Procedimientos y funciones

5.12.3.1. Sub Main() Es el procedimiento ejecutado por el sistema operativo para comenzar la ejecución del

programa.

Carga y muestra la ventana de presentación mientras carga la ventana principal (Frm_MDI) en segundo plano.

Documentación y decisiones La ventana principal se visualiza a sí misma por detrás de la ventana de presentación, de

tal forma que cuando acabe la temporización de la ventana de presentación y ésta se descargue, la ventana principal será la única operativa, haya o no haya acabado la apertura del proyecto en curso.

Flujograma

Muestra ventana de presentación (Show)

Carga ventana principal (Load)

Fin

5.12.3.2. Public Sub Sub_ActualizarFormconResultadosEjecucion() Cuando se acaba de ejecutar una orden de depuración, es necesario que los formularios

muestren los cambios que la ejecución ha provocado.

Este procedimiento llama a los procedimientos encargados de refrescar cada uno de los formularios que pueden verse afectados.

Flujograma Actualiza formulario tablas de memoria (Sub_ActualizarDBGMemU)

Page 189: DCSLLL

5 Programación

188

Actualiza cronogramas formulario simulación (Sub_ActualizarGrafico)

Actualiza representación líneas de programa (Sub_PeticionRefresco)

Fin

5.12.3.3. Public Sub Sub_ActualizarFormconMapeadoMemoria() Este procedimiento se encarga de llamar a los procedimientos encargados de actualizar

los formularios afectados cuando se produce un cambio en el mapeado de memoria.

Hay dos objetos que muestran las direcciones de memoria de usuario:

• La tabla de memoria de usuario del formulario de memoria

• La tabla de direcciones donde introducir las expresiones de evolución deseadas durante la simulación.

Flujograma Actualiza formulario tablas de memoria (Sub_ActualizarDBGMemU)

Actualiza tabla de expresiones evolución (Sub_DimensionarRstEvolucion)

Fin

5.12.4. Procedimientos y funciones de codificación y decodificación de números Los archivos asociados contienen datos en hexadecimal, que son leídos por las

funciones de Visual Basic como caracteres ASCII.

Para obtener el número que corresponde al carácter, se utiliza la función “Asc()” que devuelve un número en el rango 0-256.

La función “Chr()” realiza la función inversa a la hora de reescribir los ficheros.

5.12.4.1. Public Function Fun_LSBaEntero(Str_Cadena As String) As Integer Convierte un string de un byte LSB al valor entero correspondiente.

5.12.4.2. Public Function Fun_LSBMSBaEntero(Str_Cadena As String) As Long Convierte un string con dos bytes LSB+MSB al valor entero correspondiente.

El primer carácter corresponde al LSB, y el segundo al MSB.

Entero = (MSB*256) + LSB

5.12.4.3. Public Function Fun_MSBLSBaEntero(Str_Cadena As String) As Long Convierte un string con dos bytes MSB+LSB al valor entero correspondiente.

El primer carácter corresponde al MSB, y el segundo al LSB.

Entero = (MSB*256) + LSB

5.12.4.4. Public Function Fun_EnteroaLSBMSB(Lng_Entero As Long) As String Convierte un entero al string con dos bytes LSB+MSB correspondiente.

El primer carácter es el que resulta de convertir el resto de la división del entero entre 256.

El segundo carácter es el que resulta de convertir el cociente entero de la división del entero entre 256.

Page 190: DCSLLL

5 Programación

189

5.12.4.5. Public Function Fun_EnteroaMSBLSB(Lng_Entero As Long) As String Convierte un entero al string con dos bytes MSB+LSB correspondiente.

El primer carácter es el que resulta de convertir el cociente entero de la división del entero entre 256

El segundo carácter es el que resulta de convertir el resto de la división del entero entre 256.

5.12.5. Procedimientos y funciones de comprobación de valores válidos Comprueban que las cadenas de texto corresponden a un número en el rango adecuado

al formato seleccionado.

5.12.5.1. Public Function Fun_ValidarMemU1bit(Str_Valores As String) As Boolean Se comprueba que la cadena de texto recibida corresponde a un número binario. Sólo

puede ser “0” ó “1”.

5.12.5.2. Public Function Fun_ValidarMemU16bit(Str_Valores As String) As Boolean Se comprueba que la cadena de texto recibida corresponde a un número entero sin signo

de 16 bits.

Aunque el LM trabaja con enteros de -65535 a 65335, el signo se obtiene gracias a un bit adicional.

Así, la cadena de texto sólo es correcta si el número codificado pertenece al rango 0-65535.

5.12.5.3. Public Function Fun_ValidarMemS8bit(Str_Valores As String) As Bolean Se comprueba que la cadena de texto recibida corresponde a un número entero sin signo

de 8 bits.

Así, la cadena de texto sólo es correcta si el número codificado pertenece al rango 0-255.

5.12.6. Procedimientos y funciones de mapeado de memoria En el capítulo 5.8 Ventana de memoria interna (Frm_MDIChildMemoria), se expone la

necesidad de funciones que conviertan la posición del registro deseado en el control DBG, en la dirección (posición) de la tabla de memoria de usuario y a la inversa.

5.12.6.1. Public Function Fun_MemUPosicionaDireccion(Int_Posicion As Integer) As Integer

Convierte la posición del DBG indicada, en la dirección que le corresponde, teniendo en cuenta si existe un salto entre el final de la zona de 1 bit, y el comienzo de la de registros (dir. 4096) en el mapeado de memoria actual.

5.12.6.2. Public Function Fun_MemUDireccionaPosicion(Int_Direccion As Integer) As Integer

Convierte la dirección indicada, en la posición del DBG que le corresponde, teniendo en cuenta si existe un salto entre el final de la zona de 1 bit, y el comienzo de la de registros (dir. 4096) en el mapeado de memoria actual.

Page 191: DCSLLL

5 Programación

190

5.12.6.3. Public Function Fun_MemSPosicionaDireccion(Int_Posicion As Integer) As Integer

Convierte la posición del DBG indicada, en la dirección que le corresponde. En este caso al no existir saltos, la dirección, es la posición menos uno.

5.12.6.4. Public Function Fun_MemSDireccionaPosicion(Int_Direccion As Integer) As Integer

Convierte la dirección indicada, en la posición del DBG que le corresponde. En este caso al no existir saltos, la posición, es la dirección más uno.

5.12.6.5. Public Function Fun_DireccionMemUCorrecta(Str_NDireccion As String) As Boolean

Evalúa si la direccion contenida en la cadena de texto corresponde al mapa de memoria actual.

Flujograma Cadena de texto es un número

No Devolver falso

Fin

(0 <= Numero < final zona 1 bit ) o ( 4095 < Numero < final zona registros)

No Devolver falso

Si Devolver verdadero

Fin

5.12.6.6. Public Function Fun_DireccionMemSCorrecta(Str_NDireccion As String) As Boolean

Evalúa si la direccion contenida en la cadena de texto corresponde al mapa de memoria actual.

Flujograma Cadena de texto es un número

No Devolver falso

Fin

0 <= Numero < 4096

No Devolver falso

Si Devolver verdadero

Fin

Page 192: DCSLLL

5 Programación

191

5.13. Módulo de soporte proyecto (Mdl_Proyecto) Librería de procedimientos.

Al abrir un proyecto, el formulario Frm_MDI gestiona las llamadas a los procedimientos que permiten acceder a la información contenida en los ficheros asociados, decodificarla y guardarla en las tablas de memoria interna o de la base de datos.

Cuando el usuario selecciona en el menú guardar un proyecto, el formulario Frm_MDI gestiona las llamadas a los procedimientos que permiten acceder a la información contenida en las tablas de memoria interna o de la base de datos, codificarla y guardarla en los ficheros asociados.

Los ficheros asociados son:

*.cfg – Configuración

*.lbl – Etiquetas de direcciones

*.blb – Etiquetas de bit

*.skp – Etiquetas de líneas de salto

*.jsr – Etiquetas de líneas de subrutina

*.ace – Comentarios de direcciones

*.lce – Comentarios de líneas de programa

*.bce – Comentarios de bit

*.slm – Entorno de simulación

*.ldr – Programa

Este módulo contiene todos estos procedimientos.

5.13.1. Documentación y decisiones Para entender como funcionan los procedimientos a la hora de codificar y decodificar la

información de los ficheros de configuración, etiquetas, comentarios y programa es necesario referirse al capítulo 4.3 F3 – Documentation functions. Sin embargo existe un fichero del que todavía no se ha hablado, este fichero es el que almacena el entorno de simulación (*.slm).

5.13.1.1. Codificación y estructura básica del fichero *.slm (entorno de simulación) Para no perder los parámetros de simulación cada vez que se cerrase el proyecto, se

decidió guardar éstos en un fichero. Así los datos que se han considerado son:

• Parámetros que configuran la simulación: Líneas a ejecutar, tiempo de ciclo y tiempo total.

• Lista de direcciones de las que seguir la evoución.

• Expresiones de evolución.

Por lo que los únicos campos que no se guardan del formulario Frm_Simulacion son:

• Número de ciclos: No es necesario pues se obtiene de dividir el tiempo total entre el tiempo de ciclo.

• Parámetros de configuración de visualización de cronogramas: tiempo de inicio, tiempo de fin y divisiones del grid vertical; por considerarse de poca importancia.

Page 193: DCSLLL

5 Programación

192

Si se buscan las variables que almacenan estos datos en el programa, todas son de tipo string (cadenas de texto), excepto en el caso de tiempo de ciclo y tiempo total que son de tipo long (enteros de 4 Bytes) fácilmente convertibles a cadenas de texto.

Por ello, se ha decidido utilizar un fichero de texto (código ASCII) donde escribir cada parámetro en una línea diferente.

Así la estructura resultante del archivo *.slm es:

Pos. Descripción Nº Bytes Formato

Parámetros 1 Líneas a ejecutar 1 Línea ASCII 2 Tiempo de ciclo 1 Línea ASCII 3 Tiempo total 1 Línea ASCII

Direcciones de las que seguir la evolución 4 Número total de direcciones 1 Línea ASCII 5 Número de dirección 1 Línea ASCII 6 Se repite pos. 5 con todas las direcciones de la lista.

Expresiones de evolución 7 Número de dirección 1 Línea ASCII 8 Evolución dirección tabla 1 bit Entradas 1 Línea ASCII 9 Evolución dirección tabla 1 bit Salidas 1 Línea ASCII 10 Evolución dirección tabla 16 bits 1 Línea ASCII 11 Se repiten pos. 7, 8, 9 y 10 con todas las direcciones con alguna expresión.

Tabla 38. Estructura del fichero entorno de simulación *.slm

5.13.2. Procedimientos y funciones

5.13.2.1. Public Sub Sub_LeerFicheroConfiguracion() Rellena la tabla configuración con los datos del archivo *.cfg

Para poder abrir el proyecto, el primer fichero a abrir es el *.cfg pues es el que contiene la ruta y nombres del resto de ficheros en su interior.

La variable global Str_RutayNombreCFG contiene la ruta y el nombre del fichero de configuración que fue seleccionado por el usuario al solicitar abrir el proyecto.

Flujograma Abrir fichero de configuración *.cfg (Str_RutayNombreCFG)

Existe el fichero

No Error (Fal_fallo)

Fin

Leer línea de fichero

Escribir línea en tabla interna (Sub_EscribirRegistroConfiguracion)

… Repetir los dos últimos pasos para todas las líneas del fichero

Cerrar fichero

Actualizar mapeado de memoria (Sub_DimensionarTablasMapeadodeMemoria)

Fin

Page 194: DCSLLL

5 Programación

193

5.13.2.2. Public Sub Sub_LeerFicherosProyecto() Si no ha aparecido ningún problema al abrir el fichero de configuración, el formulario

Frm_MDI llama a este procedimiento que realiza las llamadas a las rutinas encargadas de abrir cada uno de los archivos asociados.

Flujograma Indicar progreso de apertura de ficheros (Sub_ActualizarBarradeProgreso)

Leer, decodificar y guardar los datos del archivo de etiquetas de dirección *.lbl (Sub_LeerFicheroEtiquetasDireccion)

… Repetir los dos últimos pasos para el resto de archivos: *.blb, *.skp, *.jsr, *.ace, *.bce, *.lce, *.slm, *.ldr).

Fin

5.13.2.3. Private Sub Sub_LeerFicheroEtiquetasDireccion() Rellena la tabla de etiquetas de direcciones de la base de datos, leyendo y decodificando

los datos del fichero *.lbl.

Documentación y decisiones Tal y como se comentaba en el capítulo 4.3 F3 – Documentation functions, los ficheros

de etiquetas son documentos mezcla de código hexadecimal y ASCII. Cada etiqueta ocupa un bloque de 36 Bytes, con la estructura mostrada en la Tabla 20. Estructura de los archivos de etiquetas (*.lbl ,*.blb, *.skp, *.jsr).

Estos campos deben de ser extraídos del fichero y escritos en los campos correspondientes de cada uno de los registros de la tabla, ver capítulo 5.17 Módulo de soporte para bases de datos (Mdl_BasesdeDatos). Los campos son:

• “NUMERO”: Entero.

• “ETIQUETA”: Cadena de texto (7 caracteres).

• “DESCRN1”: Cadena de texto (9 caracteres).

• “DESCRN2”: Cadena de texto (9 caracteres).

• “DESCRN3”: Cadena de texto (9 caracteres).

Flujograma Obtener ruta y nombre fichero de etiquetas *.lbl

Existe el fichero

No Fin

Abrir fichero

Leer bloque de etiqueta (36 Bytes)

Bloque leido incorrecto

Si Cerrar fichero

Fin

Extraer campo “NUMERO”: 2 Bytes

Extraer campo “ETIQUETA”: 7 Bytes

Page 195: DCSLLL

5 Programación

194

Extraer campo “DESCRN1”: 9 bytes

Extraer campo “DESCRN2”: 9 bytes

Extraer campo “DESCRN3”: 9 bytes

Guardar registro en tabla interna (Sub_EscribirRegistroEtiquetaDireccion)

… Repetir los tres últimos pasos para todas las etiquetas del fichero

Cerrar fichero

Fin

IDEM para procedimientos:

• Private Sub Sub_LeerFicheroEtiquetasBit(): fichero *.blb.

• Private Sub Sub_LeerFicheroEtiquetasSalto(): fichero *.skp.

• Private Sub Sub_LeerFicheroEtiquetasSubrutina(): fichero *.jsr.

5.13.2.4. Private Sub Sub_LeerFicheroComentariosDireccion() Rellena la tabla de comentarios de direcciones de la base de datos, leyendo y

decodificando los datos del fichero *.ace.

Documentación y decisiones Tal y como se comentaba en el capítulo 4.3 F3 – Documentation functions, los ficheros

de comentarios son documentos mezcla de código hexadecimal y ASCII. Cada, comentario ocupa un bloque de dimensión variable con la estructura mostrada en la Tabla 21. Estructura de los ficheros de comentarios (*.ace ,*.lce, *.bce).

Estos campos deben de ser extraídos del fichero y escritos en los campos correspondientes de cada uno de los registros de la tabla, ver capítulo 5.17 Módulo de soporte para bases de datos (Mdl_BasesdeDatos). Los campos son:

• “NUMERO”: Entero largo

• “NLINEAS”: Entero

• “CONTENIDO”: Cadena de texto

Flujograma Obtener ruta y nombre fichero de etiquetas *.ace

Existe el fichero

No Fin

Abrir fichero

Leer número total de comentarios (2 Bytes)

Leer número de comentario (2 Bytes)

Leer número de líneas del comentario (2 Bytes)

Leer línea (67 Bytes)

Eliminar espacios de relleno y sustituir por retorno de carro

… Repetir los dos últimos pasos para todas las líneas del comentario

Guardar registro en tabla interna (Sub_EscribirRegistroEtiquetaDireccion)

Page 196: DCSLLL

5 Programación

195

… Repetir los seis últimos pasos para todos los comentarios del fichero

Cerrar fichero

Fin

IDEM para procedimientos:

• Private Sub Sub_LeerFicheroComentariosBit(): fichero *.bce.

• Private Sub Sub_LeerFicheroComentariosLinea(): fichero *.lce.

5.13.2.5. Private Sub Sub_LeerFicheroEntornoSimulacion() Inicializa los objetos del formulario Frm_Simulación, que contienen los parámetros de

simulación a partir de los datos almacenados en el fichero *.slm.

Flujograma Obtener ruta y nombre fichero de etiquetas *.lbl

Existe el fichero

No Fin

Abrir fichero

Leer línea: Líneas a simular

Leer línea: Tiempo de ciclo

Leer línea: Tiempo total de simulación

Escribir parám. de simulación en el módulo de simulación Mdl_simulacion (Sub_EscribirConfiguracionSimulacion)

Escribir parám. de simulación en el formulario Frm_MDIChildSimulacion (Sub_RestaurarParametrosSimulacion)

Leer línea: Número total de direcciones lista seguimiento evolución

Leer línea: Número de dirección

Añadir dirección a la lista del formulario de simulación(Sub_AñadirDireccionConSeguimientoEvolucion)

… Repetir los dos últimos pasos hasta alcanzar el número total de direcciones

Leer línea: Número de dirección

Leer línea: Expresión de evolución campo 1 bit Entrada

Leer línea: Expresión de evolución campo 1 bit Salida

Leer línea: Expresión de evolución campo 16 bits

Guardar registro en tabla interna (Sub_EscribirRegistroEvolucion)

… Repetir los seis últimos pasos para todas las direcciones del fichero

Refrescar formulario de simulación (Sub_ActualizarDBGEvolucion)

Cerrar fichero

Fin

Page 197: DCSLLL

5 Programación

196

5.13.2.6. Private Sub Sub_LeerFicheroPrograma() Rellena la tabla Par_Programa (partes de programa) con los datos del fichero *.ldr.

Documentación y decisiones Tal y como se comentaba en el capítulo 4.2 F2 – 620 Stand alone loader (*.ldr), el

fichero de programa es un documento mezcla de código hexadecimal y ASCII, con la estructura mostrada en la Tabla 4. Estructura del fichero *.ldr.

Estos campos deben de ser extraídos del fichero y escritos en los registros correspondientes de la tabla de memoria interna, ver capítulo 5.16 Módulo de soporte tablas internas (Mdl_TablasInternas).

Cuando se alcance la parte de líneas de programa, es necesario evaluar los elementos identificando las líneas para separar unas de otras y así facilitar el acceso posterior a una línea en concreto. Los procedimientos encargados de esta tarea, se han desarrollado en un módulo aparte (ver el capítulo siguiente). El procedimiento Sub_LeerFicheroPrograma se limita a leer los bytes de uno en uno, siendo el otro módulo el encargado de identificarlos y escribir las líneas en la tabla correspondiente.

Flujograma Obtener ruta y nombre fichero de programa *.ldr

Existe el fichero

No Avisar del problema

Fin

Abrir fichero

Leer modelo procesador LM (2 Bytes)

Comparar con modelo según fichero configuración

No son iIguales Avisar del problema

Fin

Guardar modelo en tabla interna (Sub_EscribirRegistroPartePrograma)

Modelo de LM igual a 620-25 o 620-35

Si Habilitar simulación (Bool_EjecucionHabilitada)

No Inhabilitar simulación (Bool_EjecucionHabilitada)

Leer tamaño de memoria (2 Bytes)

Guardar tamaño de memoria en tabla interna (Sub_EscribirRegistroPartePrograma)

… Repetir los dos últimos pasos para todos los campos hasta comienzo del cuerpo.

Indicar al procedimiento separar líneas comienzo de nuevo programa (Fun_SepararLineas)

Leer siguiente Byte

Separar línea (Fun_SepararLineas)

Final de programa

No Repetir los tres últimos pasos

Page 198: DCSLLL

5 Programación

197

Leer resto de fichero (cola)

Guardar cola en tabla interna (Sub_EscribirRegistroPartePrograma)

Cerrar fichero

Fin

5.13.2.7. Public Sub Sub_EscribirFicherosUnoaUno() Solicita que tablas con datos quiere guardar el usuario en los ficheros correspondientes.

Para ello llama al formulario Frm_ModalSeleccionFicheros que permite al usuario realizar la selección y gestiona las llamadas, es por esto que los siguientes procedimientos de escritura son todos públicos y no privados como los de lectura.

Flujograma Seleccionar ficheros a escribir (Frm_ModalSeleccionFicheros)

Fin

5.13.2.8. Public Sub Sub_EscribirFicheros() Borra y vuelve a escribir los ficheros asociados al proyecto con los datos existentes

tanto en memoria interna: fichero *.cfg, como en la base de datos: ficheros *.lbl, *.blb, *.skp, *.jsr, *.ace, *.bce, *.lce, *.slm.

No se contempla reescribir el fichero de programa con los datos de memoria interna, pues el simulador no es capaz de modificar el código de programa.

Flujograma Escribir fichero configuración *.cfg (Sub_EscribirFicheroConfiguración)

… Repetir el último paso para el resto de ficheros: *.lbl, *.blb, *.skp, *.jsr, *.ace, *.bce, *.lce, *.slm).

Fin

5.13.2.9. Private Sub Sub_EscribirFicheroConfiguracion() Escribe el fichero de configuración *.cfg a partir de la tabla en memoria

correspondiente.

Realiza las operaciones del procedimiento Sub_LeerFicheroConfiguracion en sentido opuesto, consultar dicho procedimiento para las explicaciones oportunas.

Flujograma

Existe fichero

Si Borrar

Crear y abrir fichero de configuración *.cfg (Str_RutayNombreCFG)

Leer siguiente registro de la tabla interna (Fun_LeerRegistroConfiguracion)

Escribir nueva línea en fichero

… Repetir los dos últimos pasos para todos los registros de la tabla

Cerrar fichero

Fin

Page 199: DCSLLL

5 Programación

198

5.13.2.10. Public Sub Sub_EscribirFicheroEtiquetasDireccion() Escribe el fichero de etiquetas de dirección *.lbl a partir de la tabla de la base de datos

correspondiente.

Realiza las operaciones del procedimiento Sub_LeerFicheroEtiquetasDireccion en sentido opuesto, consultar dicho procedimiento para las explicaciones oportunas.

Flujograma Obtener ruta y nombre fichero de etiquetas *.lbl

Existe fichero

Si Borrar

Existen etiquetas en la tabla

No Fin

Crear y abrir fichero

Leer primera etiqueta de la tabla interna (Fun_LeerRegistroEtiquetaDireccionPorPosicion)

Escribir campo “NUMERO”: 2 Bytes

Escribir campo “ETIQUETA”: 7 Bytes

Escribir campo “DESCRN1”: 9 bytes

Escribir campo “DESCRN2”: 9 bytes

Escribir campo “DESCRN3”: 9 bytes

… Repetir los seis últimos pasos para todas las etiquetas de la tabla

Cerrar fichero

Fin

IDEM para procedimientos:

• Public Sub Sub_EscribirFicheroEtiquetasBit(): fichero *.blb.

• Public Sub Sub_EscribirFicheroEtiquetasSalto(): fichero *.skp.

• Public Sub Sub_EscribirFicheroEtiquetasSubrutina(): fichero *.jsr.

5.13.2.11. Public Sub Sub_EscribirFicheroComentariosDireccion() Escribe el fichero de comentarios de dirección *.ace a partir de la tabla de la base de

datos correspondiente.

Realiza las operaciones del procedimiento Sub_LeerFicheroComentariosDireccion en sentido opuesto, consultar dicho procedimiento para las explicaciones oportunas.

Flujograma Obtener ruta y nombre fichero de comentarios *.ace

Existe fichero

Si Borrar

Existen comentarios en la tabla

No Fin

Page 200: DCSLLL

5 Programación

199

Crear y abrir fichero

Escribir número total de comentarios (2 Bytes)

Leer primer comentario de la tabla interna (Fun_LeerRegistroComentarioDireccionPorPosicion)

Escribir número de comentario (2 Bytes)

Construir y contar número de líneas de 67 Bytes

Escribir número de líneas del comentario (2 Bytes)

Escribir líneas

… Repetir los cinco últimos pasos para todos los comentarios de la tabla

Cerrar fichero

Fin

IDEM para procedimientos:

• Public Sub Sub_EscribirFicheroComentariosBit(): fichero *.bce.

• Public Sub Sub_EscribirFicheroComentariosLinea(): fichero *.lce.

5.13.2.12. Private Sub Sub_EscribirFicheroEntornoSimulacion() Escribe el fichero *.slm a partir de las variables que conforman el entorno de

simulación.

Realiza las operaciones del procedimiento Sub_LeerFicheroEntornoSimulacion en sentido opuesto, consultar dicho procedimiento para las explicaciones oportunas.

Flujograma Obtener ruta y nombre fichero de etiquetas *.slm

Existe el fichero

Si Borrar

Crear y abrir fichero

Leer parámetros de simulación (Fun_EstadoSimulacion)

Escribir línea: Líneas a simular

Escribir línea: Tiempo de ciclo

Escribir línea: Tiempo total de simulación

Obtener lista de direcciones de seguimiento de evolución (Fun_LeerListaSeguimientoEvolucion)

Escribir línea: Número total de direcciones lista seguimiento evolución

Escribir línea: Número de dirección

… Repetir el último paso para todas las direcciones de la lista

Cambiar filtro de acceso a la tabla de expresiones de evolución a sólo los registros con alguna expresión (Sub_CambiarFiltroEvolucion)

Leer primer registro (Fun_LeerRegistroEvolucionEntradaPorPosicion)

Escribir línea: Número de dirección

Page 201: DCSLLL

5 Programación

200

Escribir línea: Expresión de evolución campo 1 bit Entrada

Escribir línea: Expresión de evolución campo 1 bit Salida

Escribir línea: Expresión de evolución campo 16 bits

… Repetir los cinco últimos pasos para todos los registros de la tabla

Cerrar fichero

Fin

Añadir dirección a la lista del formulario de simulación (Sub_AñadirDireccionConSeguimientoEvolucion)

Page 202: DCSLLL

5 Programación

201

5.14. Módulo de soporte para separar líneas de *.ldr (Mdl_SepararLineas) Librería de procedimientos.

Cuando el usuario solicita abrir un nuevo proyecto, el módulo “Mdl_Proyecto” (ver capítulo 5.13 Módulo de soporte proyecto (Mdl_Proyecto)), gestiona la apertura de todos los ficheros relacionados y realiza la decodificación de los datos para rellenar las tablas internas. Entre ellos el fichero *.ldr.

Una vez el módulo localiza la parte con el código de programa (cuerpo), necesita poder separar los elementos que corresponden a cada línea.

El módulo Mdl_SepararLineas contiene todos los procedimientos necesarios para realizar esta separación. Para ello, recibe todos lo códigos que componen el programa de uno en uno, identifica los diversos elementos de control y localiza los códigos de elementos de fin de línea para separar las líneas. A medida que se completa cada línea, la escribe en la tabla interna.

5.14.1. Documentación y decisiones Es necesario referirse al capítulo 4.2.3 Cuerpo, para entender como se codifica el

programa. A modo de resumen:

• Las líneas de programa se componen de instrucciones. Cada instrucción se codifica con uno o más grupos de 3 Bytes conocidos como elementos.

• Al principio del programa, 4 Bytes indican el número de elementos totales del programa.

• Los elementos se agrupan en bloques con un máximo de 82. Cada bloque comienza con el código h4C seguido de un Byte que indica el número de elementos de ese bloque. Si el bloque contiene temporizadores y contadores, al final del mismo el código h52 marca el comienzo de un grupo de Bytes que contiene los parámetros de dichos elementos.

Estudiando lo expuesto anteriormente, a la hora de implementar esta función, se podía optar por:

• Reconstruir las líneas evaluando todos los elementos para así detectar errores en el programa tales como instrucciones no permitidas por el modelo de procesador, errores en las secuencias…

• Detectar los elementos que codifican elementos de fin de línea (salidas, saltos…) para realizar la separación de líneas.

Como se ha decidido utilizar el programa MS-DOS Loader para realizar la edición de las líneas de programa, y éste ya evita que se produzcan errores en la programación, se ha optado por la segunda opción para evitar tiempos de procesamiento inútiles a la hora de abrir el proyecto.

5.14.1.1. Definición del registro línea Cada línea va a ser almacenada en un registro de una tabla interna.

Cada registro debe contener toda la información relativa a la línea, para obtenerla en un único acceso. Así, cada registro línea debe de estar formado por:

• Número: Número de la línea.

Page 203: DCSLLL

5 Programación

202

• Elementos: Tabla de registros con cada uno de los elementos que componen la línea.

5.14.1.2. Definición del registro elemento Cada registro debe contener toda la información relativa al elemento, para obtenerla en

un único acceso. En principio:

• Opcode: Código de instrucción (1 Byte)

• Parámetro: Código que identifica la dirección… que necesita el opcode (2 Bytes).

Elementos timer y contador Sin embargo, en el caso de un elemento temporizador o contador, éste debe de incluir

los parámetros del bloque h52 que le corresponden. En vez de crear un nuevo campo que sería inútilmente incorporado a todos los elementos aunque no fuesen de este tipo, se ha decidido añadir los códigos al final del campo “parámetro”.

El bloque de parámetros está formado por:

1 Byte Código h52.

2 Bytes Dirección del preset codificada en hexadecimal (LSB MSB).

1 Byte Código h00

2 Bytes Valor de preset codificado en hexadecimal (MSB LSB)

Como la dirección del preset es la del acumulador menos uno, no es necesario guardar este valor. Así, que finalmente el campo “parámetro” de un temporizador está compuesto por:

2 Bytes Dirección del acumulador codificada en hexadecimal (MSBLSB)

2 Bytes Valor de preset codificado en hexadecimal (MSB LSB)

Bits históricos En el capítulo 4.2.2.6 Número de elementos totales del programa forzados, se describe

como el MS-DOS Loader permite forzar elementos, sustituyendo el valor que tendría que tomar el elemento en función de la lógica, por el valor que desee el usuario.

En el capítulo 4.2.3.2 Elementos de programa, se deduce que un elemento forzado se codifica modificando los bits históricos del opcode del elemento:

• bit 41: indica con un “1” si el elemento está forzado.

• bit 52: indica en el caso de bit 4 a “1”, el valor que debe de sustituir al que tiene la dirección.

En el mismo capítulo se describe como estos bits también almacenan información del estado de estos y otros elementos que no pueden ser forzados durante la evolución del programa.

Al cambiar el valor de los bits históricos se obtienen opcodes diferentes para una misma instrucción.

1 Bit 20 si se consideran los 24 bits que codifican cada elemento (Opcode + Parámetro). 2 Bit 21 si se consideran los 24 bits que codifican cada elemento (Opcode + Parámetro).

Page 204: DCSLLL

5 Programación

203

A la hora de evaluar cada elemento cuando se esté simulando el programa, existen dos opciones:

• Evaluar cada opcode independientemente.

• No considerar los bits históricos a la hora de identificar el opcode y luego evaluar el estado de los bits históricos cuando se esté simulando el elemento.

Como se va a desarrollar un procedimiento que simule cada opcode; tanto por reducir el número de procedimientos a desarrollar como facilitar el acceso a un bit de un campo numérico (opcode), en el momento de separar las líneas se van a normalizar todos los opcodes forzados y se van a inicializar dos nuevos campos que contendrán la información de los dos bits históricos.

• Bit forzado: Indica con un “1” si el elemento está forzado (bit 4).

• Bit histórico: Indica el valor que debe de sustituir al que tiene la dirección (bit 5).

5.14.2. Procedimientos y funciones

5.14.2.1. Public Function Fun_SepararLineas(Enum_Opcion As Integer, Optional Str_CodigoParametrizado As String) As Boolean

Es el procedimiento al que llama el módulo Mdl_Proyecto, ya que es el único que es público del módulo Mdl_SepararLineas para el resto de módulos y formularios.

Con el parámetro Enum_Funcion, el usuario selecciona:

• opc_FunResetPrograma Resetear variables globales para comenzar la separación de líneas de un nuevo programa.

• opc_FunSepararLineas Nuevo código.

Flujograma Opción seleccionada (Enum_Opcion)

opc_FunResetPrograma

Reset variables de control alcance programa

Reset variables de control alcance línea (Fun_SepararLineas)

opc_FunResetLinea

Reset variables de control alcance línea

opc_FunResetElemento

Reset variables de control alcance elemento

opc_FunSepararLineas

Determinar acción en función del código (Sub_LlamaaSeparar)

Devolver si fin de programa (Bool_FinaldePrograma)

Fin

5.14.2.2. Private Sub Sub_LlamaaSeparar() Si es comienzo de nuevo elemento memoriza el código actual como opcode, para

mantenerlo durante los códigos siguientes de este mismo elemento.

Clasifica el opcode del elemento actual en curso y llama a la rutina correspondiente.

Page 205: DCSLLL

5 Programación

204

Si las rutinas siguientes indican final de línea guarda el código en el registro de la tabla interna, y comienza nueva línea.

Flujograma Comienzo de nuevo elemento

Si Actualizar Opcode elemento actual (Str_OpcodeElementoActual)

Determinar acción en función del opcode elemento actual

Comienzo de bloque

Reset variables de control alcance bloque (Sub_ComienzodeBloque)

Elemento forzado

Normalizar opcode y guardar campos “bit forzado” y “bit histórico”

Evaluar elemento (Sub_LlamaaSeparar)

Elemento no terminador de línea

Evaluar elemento (Sub_OpcodedeNoTerminador)

Elemento terminador de línea

Evaluar elemento (Sub_OpcodedeTerminador)

Código h4E

Final de programa

Si Evaluar elemento (Sub_FindePrograma)

No Evaluar elemento (Sub_OpcodedeNoTerminador)

Parámetros contador/temporizador

Evaluar elemento (Sub_ParametrosContadorTemporizador)

Fin de programa

Evaluar elemento (Sub_FindePrograma)

Código de matriz o de secuenciador

Avisar de error y abortar procedimiento

Otro código

Avisar de error y abortar procedimiento

Final de elemento

Si Actualizar número de elementos pendientes

Añadir elemento al campo “Elementos” de la línea actual

Final de línea

Si Añadir código línea actual en registro tabla interna (Sub_EscribirRegistroLineadePrograma)

Reset variables de control alcance línea (Fun_SepararLineas)

Fin

Page 206: DCSLLL

5 Programación

205

5.14.2.3. Private Sub Sub_ComienzodeBloque() Cada bloque tiene la siguiente estructura:

1 Byte Opcode (h4C). 1 Byte Número de elementos codificado en hexadecimal

Si es primer código de elemento, se indica que queda 1 código más.

Si es el segundo inicializa la variable global que contiene el número de elementos del bloque en curso.

Flujograma Comienzo de nuevo elemento

Si Número códigos pendientes elemento = 1 (Int_NCodigosPdtesElemento)

No Inicializar número de elementos bloque (Int_NCodigosPdtesBloque)

Decrementar número códigos pendientes elemento

Reset número de temporizadores/contadores en bloque

Fin

5.14.2.4. Private Sub Sub_OpcodedeNoTerminador() Si es primer código de elemento, se indica que quedan dos códigos más y decrementa

las variables globales que guardan el número de elementos pendientes.

Si el opcode corresponde a un temporizador o contador es necesario guardar el número de línea y el número del elemento en el que aparece, para que luego el procedimiento Sub_ParametrosContadorTemporizador a la hora de recuperar los parámetros que le corresponden sepa en que elemento escribirlos. Estos números se almacenan en la variable global Lng_MatrizNLineaTimers.

Flujograma Comienzo de nuevo elemento

Si Número códigos pendientes elemento = 2 (Int_NCodigosPdtesElemento)

Código de temporizador o contador

Si Guardar número de línea y elemento (Lng_MatrizNLineaTimers)

No Guardar Byte en campo “parametro”

Decrementar número códigos pendientes elemento

Elementos pendientes elementos = 0

Si Indicar final de elemento (Bool_FinaldeElemento)

Fin

5.14.2.5. Private Sub Sub_OpcodedeTerminador() Si es primer código de elemento, se indica que quedan dos códigos más y decrementa

las variables globales que guardan el número de elementos pendientes.

Una vez se acaban de recibir los 3 Bytes que pertenecen al elemento con un opcode de instrucción de final de línea, se indica el fin de línea para que el procedimiento Sub_LlamaaSeparar guarde el código en el registro de la tabla interna.

Page 207: DCSLLL

5 Programación

206

La única excepción es la instrucción de salto a subrutina (JSR) ya que esta instrucción está formada por dos elementos de tres bytes ambos con el opcode h04, por lo que el primer elemento no se considera final de línea.

Flujograma Comienzo de nuevo elemento

Si Número códigos pendientes elemento = 2 (Int_NCodigosPdtesElemento)

No Guardar Byte en campo “parametro”

Decrementar número códigos pendientes elemento

Final de elemento

Si Indicar final de elemento (Bool_FinaldeElemento)

Primer elementos JSR

No Indicar final de línea (Bool_FinaldeLinea)

Fin

5.14.2.6. Private Sub Sub_ParametrosContadorTemporizador() Al final del bloque h4C el código h52 indica el comienzo de los parámetros de los

temporizadores o contadores que hayan podido existir.

Así, se tenía la siguiente estructura:

1 Byte Opcode (h52). 1 Byte Número de temporizadores/contadores en el bloque codificado en hexadecimal. A su vez indica el número de veces que se repite el siguiente bloque, pues hay uno por cada uno de los temporizadores/contadores 2 Bytes Dirección Preset codificada en hexadecimal (LSB MSB) 1 Byte Código h00 2 Bytes Valor de temporización codificado en hexadecimal (MSB LSB)

Tal y como se ha decidido al comienzo de éste capítulo esta función escribe los códigos al final del campo “parametro” del registro de la tabla interna que contiene el elemento temporizador o contador al que corresponde, añadiendo la estructura:

2 Bytes Valor de temporización codificado en hexadecimal (MSB LSB)

Para ello, una vez obtenido el valor PRESET, llama a Sub_AñadeTimerEnLinea.

Flujograma

Estado del elemento

Comienzo de elemento (0)

Número códigos pendientes elemento = -1 (Int_NCodigosPdtesElemento)

Comenzado pero no inicializado (-1)

Número códigos pendientes elemento = 5 * N (Int_ NCodigosPdtesElemento)

Reset nuevo bloque de parámetros

Recuperar primer número línea con código de temporizador o contador (Lng_MatrizNLineaTimers)

Comenzado e inicializado

Page 208: DCSLLL

5 Programación

207

Añadir código a bloque de parámetros actual

Decrementar número códigos pendientes bloque de parámetros actual

Fin del bloque de parámetros actual

Si Añadir valor del PRESET al elemento (Sub_AñadeTimerenLinea)

Reset nuevo bloque de parámetros

Recuperar siguiente número línea con código de temporizador o

Decrementar número códigos pendientes elemento

Fin

5.14.2.7. Private Sub Sub_FindePrograma() Si el número de elementos pendientes del programa es cero indica fin de programa para

que el módulo Mdl_Proyecto sepa que se ha acabado la parte de código (Bool_FinaldePrograma).

5.14.2.8. Private Sub Sub_AñadeTimerenLinea(Int_IdicePosicionTimer As Integer, Str_ValorPreset As String)

Recupera el número de línea y de elemento guardados en el registro de la tabla NLNT_MatrizPosiciontimers con el índice indicado, y añade al campo “parámetro” el valor del preset parametrizado.

Page 209: DCSLLL

5 Programación

208

5.15. Módulo de soporte interpretar líneas (Mdl_InterpretarLineas) Librería de procedimientos.

Este módulo se encarga de interpretar los elementos que componen la línea de programa solicitada por el formulario de visualización del programa, devolviendo una variable con los datos que, copiados sobre el control gráfico del formulario, permitirán su visualización (ver capítulo 5.9 Ventana de programa (Frm_MDIChildPrograma)).

5.15.1. Documentación y decisiones

5.15.1.1. Módulo de simulación e interpretación independientes Se podría trabajar de tal forma que al mismo tiempo que las líneas son evaluadas para

ser ejecutadas, podrían ser interpretadas para ser visualizadas.

Esta forma de trabajar presenta las siguientes ventajas:

• El mismo procedimiento realizaría las dos funciones, reduciendo las líneas de código y el tiempo de procesamiento.

Pero también presenta los siguientes inconvenientes:

• Complica la realización del programa al mezclar funciones.

• Como se quiere que el usuario pueda visualizar la línea que desee cuando se está depurando el programa, se tendrían que tener todas las líneas interpretadas en memoria, para no interrumpir la secuencia del ciclo de ejecución de programa.

Por ello, se va a realizar un módulo encargado de la simulación y otro encargado de la visualización.

5.15.1.2. Relación entre el módulo de simulación y el de visualización En un principio se pensó que el módulo de simulación y el módulo de visualización

funcionasen de forma independiente, así, el módulo de simulación modificaría los registros de memoria de usuario de acuerdo a la ejecución de las líneas de programa, mientras que la ventana de visualización presentaría debajo de cada uno de los elementos, el valor del registro de memoria en ese momento.

Módulo desimulación

Memoria deregistros

Memoria deprograma

Ventana devisualización

Figura 59. Opción 1: Módulos de simulación y visualización independientes

Este método implica que, si el usuario quiere supervisar la ejecución de una línea, sería necesario que se comprobasen los valores de los elementos de la línea antes y después de ejecutarla.

Si en vez de una línea se ejecuta un ciclo completo, los valores de los elementos de entrada presentados por las líneas no tendrían por que ser iguales a los valores que fueron evaluados en su momento, al poder ser los valores mostrados el resultado de los cambios producidos por líneas posteriores.

Si se quiere tener una potente herramienta de depuración, es necesario que la ventana de visualización presente el estado que tenía el elemento de entrada antes de ejecutar la línea y el elemento de salida el resultado obtenido, tanto depurando de línea en línea como de ciclo en ciclo.

Page 210: DCSLLL

5 Programación

209

Esto complica y hace más lento el proceso, pues aparece la necesidad de un elemento intermedio que almacene el estado de cada uno de los elementos de todas las líneas que forman el programa, para así poder visualizar los cambios producidos de ciclo en ciclo.

Módulo desimulación

Memoria deregistros

Memoria deprograma

Ventana devisualización

Valores deevolución de

elementos

Figura 60. Opción 2: Módulos de simulación y visualización relacionados mediante tabla adicional

Al igual que hace el LM que almacena los bits históricos como parte del opcode del elemento, se van a añadir en cada uno de los registros que contienen los elementos de una línea, los campos que permitan almacenar los valores de estado necesarios.

De esta forma, se reduce la memoria necesaria y se aumenta la velocidad de acceso al guardar los valores de evolución en el mismo registro de la tabla que ha sido anteriormente leído para determinar la ejecución normal del scan de programa.

Módulo desimulación

Memoria deregistros

Memoria deprograma

Ventana devisualización

Valores deevolución de

elementos

Figura 61. Opción 3: Módulos de simulación y visualización relacionados mediante la

tabla de líneas de programa

Valores de evolución de elementos Es necesario determinar qué valores necesitan ser guardados.

Valores enteros

En el caso de elementos que codifican instrucciones que operan con números enteros, el valor entero a almacenar depende del tipo de instrucción:

• Elemento de entrada: Valor leído.

• Elemento de salida: Valor escrito.

Como un elemento no puede ser de entrada y de salida, basta con un campo para guardar el valor correspondiente al tipo de elemento (campo “valor16bits”).

Sin embargo, en el caso de temporizadores y contadores, en el mismo elemento es necesario guardar dos valores enteros: el valor del acumulador y el del preset. Por lo que, aunque en la mayoría de elementos no será necesario, se necesita un campo adicional para guardar éste valor extra (campo “valor16bitsPRS”).

Page 211: DCSLLL

5 Programación

210

Estado de la lógica

Para poder colorear de verde la secuencia lógica verdadera a lo largo de las formaciones serie o paralelo que forman la línea de programa, se necesita guardar el valor de la lógica en ese momento.

Para facilitar la propagación del estado lógico, se van a guardar dos campos con los valores lógicos del elemento antes (campo “valor1bitAntes”) y después (campo “valor1bitDespues”) de su contribución a la lógica.

Valores de evolución de líneas Si una línea no es ejecutada, todos los campos de estado de los elementos van a ser cero.

Es necesario indicar esta situación, para que el usuario no pueda pensar que la secuencia lógica del primer elemento no se cumple o que existe un error en el programa.

Dentro de la secuencia normal de ejecución, existen tres casos excepcionales por los que una línea no es ejecutada:

• Se ha seleccionado la orden de depuración “No ejecutar línea”. (Línea no ejecutada).

• La línea está dentro de un bloque de salto (NSK) activo. (Línea saltada).

• La línea no está incluida dentro del rango de líneas a simular. (Línea no ejecutada).

Esta información va a ser almacenada en un campo adicional del registro línea (campo “HaSidoSaltada”) cuyo valor será:

• 0 – Línea ejecutada.

• 1 – Línea saltada.

• 2 – Línea no ejecutada.

5.15.1.3. Decodificación de los elementos Una vez el módulo simulador ha guardado el estado en los elementos de la tabla interna

de líneas de programa, para visualizar la línea solicitada por el usuario, es necesario decodificar los elementos y rellenar la variable (línea gráfica) con los datos que necesita el formulario de visualización.

En el capítulo 5.9 Ventana de programa (Frm_MDIChildPrograma), se describe como la línea gráfica es una tabla de registros de 21 columnas y un máximo de 5 filas, cuyos datos serán copiados sobre las celdas de un control gráfico donde se visualizará la línea. Ver Figura 55. Composición de la línea gráfica.

Los datos a escribir en cada celda eran:

• Imagen: Cadena de texto con la referencia de la imagen (símbolo) a utilizar.

• Estado: Cadena de texto con la referencia de la imagen (color de estado) a utilizar.

• Texto: Cadena de texto a visualizar en la celda.

• Información: Cadena de texto a visualizar en el cuadro de texto que presenta los datos de los archivos de documentación.

La columna 0 contiene los datos comunes de información de la línea, mientras que las columnas 1-20 delimitan la zona donde representar las instrucciones.

Page 212: DCSLLL

5 Programación

211

Cuando una instrucción es evaluada, principalmente se realizan dos tipos de acciones:

• Progresión por la matriz de celdas: Determinan el movimiento sobre la cuadrícula. Por ejemplo, el código “bifurcación descendente en T” provoca bajar a la fila inferior, mientras que el código “contacto normalmente abierto” avanza a la siguiente posición de la misma fila.

• Escritura de Datos: Determinan qué datos escribir en los campos de cada una de las celdas de la línea gráfica. Por ejemplo, el código “contacto normalmente abierto” evalúa el estado lógico únicamente para determinar el color, mientras que el código “constante entera”, además, debe de evaluar el campo parámetro para escribir el valor a presentar.

Excepcionalmente, los campos de las celdas de interconexión van a ser rellenados con las acciones de progresión, ya que, en el momento en que se progresa por las celdas, resulta más fácil determinar que imagen y estado corresponde a cada una.

Acciones de progresión Cada instrucción, modifica de forma diferente las tres variables globales que controlan

la progresión. Cada una de estas variables define una posición (columna, fila) en la matriz gráfica

• Posición actual: Indica la celda del elemento que se está evaluando en ese momento.

• Posición siguiente: Indica la celda que ocupará el siguiente elemento que será evaluado.

• Posición rama paralelo pendiente: Cuando se evalúa un elemento que implica un cambio de fila, guarda la columna de la fila inferior en la que situarse cuando el salto se produzca, o la columna a la que regresar cuando se regrese de la fila inferior. Esta variable es una tabla de cinco posiciones, una para cada fila.

La forma de progresar entre las celdas es:

• Se comienza en la celda 2,0.

• Por las columnas se avanza de dos en dos, lo que implica que siempre se estará en una columna par, pues son las ocupadas por los símbolos de los elementos, rellenándose automáticamente las columnas impares con las imágenes de interconexión adecuadas a la progresión definida por el elemento.

Las instrucciones pueden ser agrupadas según las acciones de progresión que realizan. Así se han obtenido 10 tipos distintos:

• Tipo 1: Operando

• Tipo 2: Operando + bifurcación anterior en T

• Tipo 3: Operando + bifurcación anterior en X

• Tipo 4: Salida

• Tipo 5: Bifurcación descendente en T

• Tipo 6: Bifurcación descendente en X

• Tipo 7: Bifurcación ascendente en T

• Tipo 8: Temporizador retentivo

Page 213: DCSLLL

5 Programación

212

• Tipo 9: Contador

• Tipo 10: Temporizador retardo

La siguiente tabla asigna el grupo al que corresponde cada instrucción:

INSTRUCCIÓN SIMBOLO CODIGOTIPO

PROGR.Instrucciones de contactos y bobinasContacto normalmente abierto -] [- C8 1Contacto normalmente abierto - bifurcación anterior en T C9 2Contacto normalmente abierto - bifurcación anterior en X CA 3Contacto normalmente cerrado -]/[- CC 1Contacto normalmente cerrado - bifurcación anterior en T CD 2Contacto normalmente cerrado - bifurcación anterior en X CE 3Contacto transicional a ON -]/\]- 43 1Contacto transicional a OFF -]\/[- 4B 1Salida no retentiva -( )- C4 4Salida retentiva -(R)- C5 4salida latch -(L)- C6 4Salida unlatch -(U)- C7 4Instrucciones de bit simpleLectura de bit -]BR[- 03 1Escribir bit -(BW)- 85 4Ramas serie y paraleloBifurcación descendente en T C1 5Bifurcación descendente en X C2 6Bifurcación ascendente en T C3 7Instrucciones de temporizadores y contadoresTemporizador retardo a ON 1 segundo -(TON)- 4A 10Temporizador retardo a ON 0.1 segundos -(TON)- 49 10Temporizador retardo a ON 0.01 segundos -(TON)- 68 10Temporizador retardo a OFF 1 segundo -(TOFF)- 42 10Temporizador retardo a OFF 0.1 segundos -(TOFF)- 41 10Temporizador retardo a OFF 0.01 segundos -(TOFF)- 60 10Temporizador retentivo 1 segundo -(TON)- 4E 8Temporizador retentivo 0.1 segundos -(TON)- 4D 8Temporizador retentivo 0.01 segundos -(TON)- 6C 8Contador CTU/CTD 4F 9Instrucciones de saltoNo salto con retención NSKR 46 4No salto con desactivación NSKD 47 4Fin de salto EOS 34 4Instrucciones de manipulación de datosLectura de datos (Bring in) -[B2]- 88 1Lectura de datos indirecta -<B2>- 89 1Lectura de datos en coma flotante -[FP]- A8 1Escritura de datos -(S2)- 07 4Escritura de datos indirecta -(I2)- 06 4Escritura de datos en coma flotante -(FP)- 27 4Constante -[K2]- 8B 1Constante en coma flotante (primera palabra) -[FPK]- 9B 1Lectura de datos 1-8 bloques de 16 bits zona I/O (PULL) -[PUL]- 80 1Lectura de datos 1-8 bloques de 16 bits zona Reg. (PULL) -[PUL]- 82 1Escritura de datos 1-8 bloques de 16 bits zona I/O (PUSH) -(PSH)- 84 4Escritura de datos 1-8 bloques de 16 bits zona Reg. (PUSH) -(PSH)- 86 4Lectura de datos tabla estados del sistema (PULS) -[PULS]- 81 1Instrucciones de comparación de enterosIgual que -]=[- 08 1Menor que -]<[- 09 1Mayor que -]>[- 0A 1Prueba de cero -]Z[- 8D 1

Tabla 39. Grupo al que corresponde cada instrucción según acciones de progreso (1/2)

Page 214: DCSLLL

5 Programación

213

INSTRUCCIÓN SIMBOLO CODIGOTIPO

PROGR.Instrucciones matemáticasSuma -[+]- 0E 1Suma con dirección de error -[+]- 0E 1Resta -[-]- 0D 1Resta con dirección de error -[-]- 0D 1Multiplicación -[*]- 0C 1Multiplicación con dirección de error -[*]- 0C 1División -[/]- 0B 1División con dirección de error -[/]- 0B 1Instrucciones de operadores lógicosAND bloque de 16 bits -[&]- 2C 1OR bloque de 16 bits -[OR]- 2E 1XOR bloque de 16 bits -[XOR]- 3E 1Instrucciones de referencia de memoriaSalto a subrutina JSR 04 4Subrutina SUB 24 4Retorno a subrutina RTS 14 4Retorno a principio de programa RBP 05 4Instrucciones de conversión de datosConversión binario a BCD -[BCD]- 1F 1Conversión binario a BCD con dirección de error -[BCD]- 1F 1Conversión BCD a binario -[BIN]- 0F 1Conversión BCD a binario con dirección de error -[BIN]- 0F 1Conversión entero a coma flotante -[FLT]- 2F 1Conversión entero a coma flotante con dirección de error -[FLT]- 2F 1Conversión coma flotante a entero -[INT]- 3F 1Conversión coma flotante a entero con dirección de error -[INT]- 3F 1Valor absoluto -[ABS]- 1C 1Valor absoluto con dirección de error -[ABS]- 1C 1Raiz cuadrada -[SQRT]- 2D 1Raiz cuadrada con dirección de error -[SQRT]- 2D 1Complemento a dos bloque de 16 bits (Negacion) -[NEG]- 1E 1Inversión de bits bloque de 16 bits (Not) -[NOT]- 1D 1Instrucciones diversasRetardo (DLA) -[DLA]- CF 1Operación nula NOP FF 1Operación nula NOP 00 1Exploración estado entradas ISS 8F 1Instrucciones no descritas en el manualInversor lógico -]o[- CB 1Codigos de controlMarcador/comentario de línea C0 --

Tabla 40. Grupo al que corresponde cada instrucción según acciones de progreso (2/2)

El funcionamiento de cada uno de estos tipos es descrito en la subrutina que lleva su nombre.

Acciones de datos

Las instrucciones pueden ser agrupadas según las acciones de datos que realizan. Así se han obtenido 17 tipos distintos (el tipo 13 fue desestimado por lo que no se lista):

• Tipo 1: Operando con dirección a 1 bit

• Tipo 2: Operando con dirección a 16 bits

• Tipo 3: Operando bit

• Tipo 4: Temporizador retardo

Page 215: DCSLLL

5 Programación

214

• Tipo 5: Temporizador retentivo

• Tipo 6: Operando salto

• Tipo 7: Operador

• Tipo 8: Operador con direccion de error

• Tipo 9: Operando datos 1-8 bloques de 16 bits zona I/O (PULL)

• Tipo 10: Operando datos 1-8 bloques de 16 bits zona registros (PULL)

• Tipo 11: Operando subrutina

• Tipo 12: Operando constante

• Tipo 14: Contador

• Tipo 15: Constante en coma flotante

• Tipo 16: Lectura de datos tabla estados del sistema (PULS)

• Tipo 17: Salto a subrutina

• Tipo 18: Marcador comentario de línea

Page 216: DCSLLL

5 Programación

215

La siguiente tabla asigna el grupo al que corresponde cada instrucción:

INSTRUCCIÓN SIMBOLO CODIGOTIPO

DATOSInstrucciones de contactos y bobinasContacto normalmente abierto -] [- C8 1Contacto normalmente abierto - bifurcación anterior en T C9 1Contacto normalmente abierto - bifurcación anterior en X CA 1Contacto normalmente cerrado -]/[- CC 1Contacto normalmente cerrado - bifurcación anterior en T CD 1Contacto normalmente cerrado - bifurcación anterior en X CE 1Contacto transicional a ON -]/\]- 43 1Contacto transicional a OFF -]\/[- 4B 1Salida no retentiva -( )- C4 1Salida retentiva -(R)- C5 1salida latch -(L)- C6 1Salida unlatch -(U)- C7 1Instrucciones de bit simpleLectura de bit -]BR[- 03 3Escribir bit -(BW)- 85 3Ramas serie y paraleloBifurcación descendente en T C1 --Bifurcación descendente en X C2 --Bifurcación ascendente en T C3 --Instrucciones de temporizadores y contadoresTemporizador retardo a ON 1 segundo -(TON)- 4A 4Temporizador retardo a ON 0.1 segundos -(TON)- 49 4Temporizador retardo a ON 0.01 segundos -(TON)- 68 4Temporizador retardo a OFF 1 segundo -(TOFF)- 42 4Temporizador retardo a OFF 0.1 segundos -(TOFF)- 41 4Temporizador retardo a OFF 0.01 segundos -(TOFF)- 60 4Temporizador retentivo 1 segundo -(TON)- 4E 5Temporizador retentivo 0.1 segundos -(TON)- 4D 5Temporizador retentivo 0.01 segundos -(TON)- 6C 5Contador CTU/CTD 4F 14Instrucciones de saltoNo salto con retención NSKR 46 6No salto con desactivación NSKD 47 6Fin de salto EOS 34 6Instrucciones de manipulación de datosLectura de datos (Bring in) -[B2]- 88 2Lectura de datos indirecta -<B2>- 89 2Lectura de datos en coma flotante -[FP]- A8 1Escritura de datos -(S2)- 07 2Escritura de datos indirecta -(I2)- 06 2Escritura de datos en coma flotante -(FP)- 27 1Constante -[K2]- 8B 12Constante en coma flotante (primera palabra) -[FPK]- 9B 15Lectura de datos 1-8 bloques de 16 bits zona I/O (PULL) -[PUL]- 80 9Lectura de datos 1-8 bloques de 16 bits zona Reg. (PULL) -[PUL]- 82 10Escritura de datos 1-8 bloques de 16 bits zona I/O (PUSH) -(PSH)- 84 9Escritura de datos 1-8 bloques de 16 bits zona Reg. (PUSH) -(PSH)- 86 10Lectura de datos tabla estados del sistema (PULS) -[PULS]- 81 16Instrucciones de comparación de enterosIgual que -]=[- 08 7Menor que -]<[- 09 7Mayor que -]>[- 0A 7Prueba de cero -]Z[- 8D 1

Tabla 41. Grupo al que corresponde cada instrucción según acciones de datos (1/2)

Page 217: DCSLLL

5 Programación

216

INSTRUCCIÓN SIMBOLO CODIGOTIPO

DATOSInstrucciones matemáticasSuma -[+]- 0E 8Suma con dirección de error -[+]- 0E 8Resta -[-]- 0D 8Resta con dirección de error -[-]- 0D 8Multiplicación -[*]- 0C 8Multiplicación con dirección de error -[*]- 0C 8División -[/]- 0B 8División con dirección de error -[/]- 0B 8Instrucciones de operadores lógicosAND bloque de 16 bits -[&]- 2C 7OR bloque de 16 bits -[OR]- 2E 7XOR bloque de 16 bits -[XOR]- 3E 7Instrucciones de referencia de memoriaSalto a subrutina JSR 04 17Subrutina SUB 24 11Retorno a subrutina RTS 14 11Retorno a principio de programa RBP 05 7Instrucciones de conversión de datosConversión binario a BCD -[BCD]- 1F 8Conversión binario a BCD con dirección de error -[BCD]- 1F 8Conversión BCD a binario -[BIN]- 0F 8Conversión BCD a binario con dirección de error -[BIN]- 0F 8Conversión entero a coma flotante -[FLT]- 2F 8Conversión entero a coma flotante con dirección de error -[FLT]- 2F 8Conversión coma flotante a entero -[INT]- 3F 8Conversión coma flotante a entero con dirección de error -[INT]- 3F 8Valor absoluto -[ABS]- 1C 8Valor absoluto con dirección de error -[ABS]- 1C 8Raiz cuadrada -[SQRT]- 2D 8Raiz cuadrada con dirección de error -[SQRT]- 2D 8Complemento a dos bloque de 16 bits (Negacion) -[NEG]- 1E 7Inversión de bits bloque de 16 bits (Not) -[NOT]- 1D 7Instrucciones diversasRetardo (DLA) -[DLA]- CF 12Operación nula NOP FF 7Operación nula NOP 00 7Exploración estado entradas ISS 8F 7Instrucciones no descritas en el manualInversor lógico -]o[- CB 7Codigos de controlMarcador/comentario de línea C0 18

Tabla 42. Grupo al que corresponde cada instrucción según acciones de datos (2/2)

El funcionamiento de cada uno de estos tipos es descrito en la subrutina que lleva su nombre.

5.15.2. Procedimientos y funciones públicas

5.15.2.1. Public Function Fun_InterpretarLinea(Lng_NLineaSolicitada As Long) As LineaDibujo

Esta función es la llamada por el formulario de visualización indicando que línea quiere visualizar.

Si la línea solicitada es correcta, la interpreta y devuelve la línea gráfica: variable que contiene la tabla de registros de 21xN filas con los datos correspondientes. Si no es correcta devuelve una tabla de 21x5 de registros vacíos.

Page 218: DCSLLL

5 Programación

217

Flujograma Existe la línea solicitada

No Inicializar línea gráfica (línea gráfica en blanco)

Si Leer línea de programa solicitada (Fun_LeerRegistroLineaPrograma)

Interpretar elementos y rellenar línea gráfica (Sub_RellenarMatrizconLinea)

Devuelve la línea gráfica resultante

Fin

5.15.2.2. Private Sub Sub_RellenarMatrizconLinea() Este procedimiento gestiona las variables de alcance línea.

Documentación y decsiones Por estar la columna 0 dedicada a la información de la línea es el encargado de

inicializarla. En la celda 0,0 escribe los datos de la línea (campos: “imagen”, “estado” y “texto”), mientras que deja en blanco las celdas 0,1 a 0,4. El campo “información”, será rellenado posteriormente si la línea contiene el elemento “Comentario de línea”.

Posteriormente se accede consecutivamente a cada uno de los elementos, llamando a la función Sub_RellenarMatrizconElemento para que ésta rellene el resto de celdas.

En el apartado que desarrolla el procedimiento Sub_Tipo2VariablesdeProgreso, se explica por que es necesario determinar si existe un timer retentivo o un contador en la línea.

Flujograma Inicializa tabla de registros a 21x5

Inicializa variables de control de progreso a celda 2,0.

Inicializa celda 0,0 con datos de línea: imagen, estado y texto.

Se está simulando un programa (Bool_SimulacionInicializada)?

Si Indicar si la línea fue saltada o no ejecutada (HaSidoSaltada).

Inicializa celdas 0,1 a 0,4.

Determina si existe un timer retentivo en la línea (Fun_ExisteTimerRetentivo)

Determina si existe un contador en la línea (Fun_ExisteContador)

Leer primer elemento

Interpretar elemento (Sub_RellenarMatrizconElemnto)

… Repetir los dos últimos pasos hasta interpretar el último elemento.

Redimensionar filas de la tabla de registros a las filas ocupadas por la línea actual.

Fin

5.15.2.3. Private Sub Sub_RellenarMatrizconElemento() Identifica el elemento recibido en función del opcode, y de acuerdo a la clasificación de

las tablas Tabla 39, Tabla 40, Tabla 41 y Tabla 42, llama al procedimiento que le corresponde tanto de acciones de progreso como de datos.

Page 219: DCSLLL

5 Programación

218

Flujograma Identificar opcode del elemento actual (Ele_actual)

Contacto normalmente abierto (hC8)

Acciones de progresión (Sub_Tipo1VariablesdeProgreso)

Acciones de datos (Sub_Tipo1VariablesdeDatos)

… Repetir para todos los opcodes.

Fin

5.15.3. Procedimientos y funciones de acciones de progreso

5.15.3.1. Private Sub Sub_Tipo1VariablesdeProgreso() Agrupa los elementos de tipo operando.

Documentación y decisiones Se progresa dentro de la fila actual. La celda actual es la que estaba marcada como

siguiente, mientras que la siguiente es la actual + 2.

- --[ ]-- ELEMENTOACTUAL

posición siguiente antes

posición actual antes

posición siguiente después

posición actual despuésImágen: línea horizontal

Estado: campo "valor1bitantes"

Figura 62. Esquema de progresión del tipo 1

Sólo queda rellenar la celda de interconexión anterior con una línea horizontal y en el caso de estar depurándose el programa, utilizar el estado lógico del campo “valorbit1Antes”del elemento que se está evaluando.

5.15.3.2. Private Sub Sub_Tipo2VariablesdeProgreso() Agrupa los elementos de tipo operando + bifurcación anterior en T.

Documentación y decisiones

Hay que recordar que en los elementos lógicos anteriores a un temporizador retentivo o un contador, un código de bifurcación descendente en T significa directamente cambiar de fila: una fila para el caso del contador y dos para el del temporizador. Éste es el motivo por el que al comenzar una nueva línea se determina si existe uno de estos elementos en la misma.

Si no existe ninguno de estos elementos, el funcionamiento es el descrito en el apartado 4.2.3.18 Interconexión de elementos donde se describe como se codifican las ramas en paralelo.

Page 220: DCSLLL

5 Programación

219

1001 1002 1003 1004 1005 1006 1007 1008 1009 4001 ├──] [─────] [──┬──] [─────] [─────] [─────] [─────] [─────] [─────] [─────( )── │ │ │ │ │ 2001 2002 │ ├──] [──┬──] [──┴ │ │ │ │ │ 3001 │ ├──] [──┴

Figura 63. Puntos clave en la codificación de ramas en paralelo

• PUNTO 1 (Ramificación pendiente): Antes del elemento a codificar existe una fila de interconexión con la fila inferior. Se guarda la posición en la que comenzarán los elementos de la fila inferior y se continúan codificando los elementos de la fila actual.

• PUNTO 2 (Cambio a fila inferior): Existe una ramificación pendiente y aparece una nueva ramificación en la fila. Se empiezan a codificar los elementos de la fila inferior, comenzando en la posición guardada en el punto 1. Se guarda la posición a la que volver cuando se regrese de la fila inferior.

• PUNTO 3 (Cambio a fila inferior y ramificación pendiente): Existe una ramificación pendiente, aparece una nueva ramificación en la fila y antes del elemento a codificar existe una fila de interconexión con la fila inferior. Se empiezan a codificar los elementos de la fila inferior, comenzando en la posición guardada en el punto 1. Se guarda la posición en la que comenzarán los elementos de la fila inferior.

• PUNTO 4 (Regreso a fila superior): Existe una fila de interconexión con la fila superior. Se continúan codificando los elementos de la fila superior, comenzando en la posición guardada en el punto 2 o 3.

El tipo 2 está relacionado con los puntos 1 y 2.

Por cambiar a una fila inferior se incrementa la variable global que contiene el número de filas que ocupa la línea actual.

5.15.3.3. Private Sub Sub_Tipo3VariablesdeProgreso()

Agrupa los elementos de tipo operando + bifurcación anterior en X.

El tipo 3 está relacionado con el punto 3 de la Figura 63.

Por cambiar a una fila inferior se incrementa la variable global que contiene el número de filas que ocupa la línea actual.

5.15.3.4. Private Sub Sub_Tipo4VariablesdeProgreso()

Agrupa los elementos de tipo salida.

Directamente se selecciona la celda 20,0 como actual.

Como se produce un salto hasta la columna 20, es necesario localizar la última columna ocupada en la fila 0, y entonces propagar el estado de la misma y dibujar una línea horizontal hasta alcanzar el elemento de salida.

PUNTO 3

PUNTO 4

PUNTO 2

PUNTO 1

Page 221: DCSLLL

5 Programación

220

5.15.3.5. Private Sub Sub_Tipo5VariablesdeProgreso() Corresponde al elemento “Bifurcación descendente en T”.

Es aplicable todo lo expuesto en el tipo 2. La diferencia es que este elemento no realiza posteriormente acciones de datos, será el próximo elemento quien ocupe la celda siguiente. Es por esto que la celda siguiente apunta a la celda actual.

5.15.3.6. Private Sub Sub_Tipo6VariablesdeProgreso() Corresponde al elemento “Bifurcación descendente en X”

Es aplicable todo lo expuesto en el tipo 3. La diferencia es que este elemento no realiza posteriormente acciones de datos, será el próximo elemento quien ocupe la celda siguiente. Es por esto que la celda siguiente apunta a la celda actual.

5.15.3.7. Private Sub Sub_Tipo7VariablesdeProgreso() Agrupa los elementos de tipo “Bifurcación ascendente en T”.

El tipo 7 está relacionado con el punto 4 de la Figura 63.

- --[ ]--

Posición siguiente después

Posición actual después

Posición siguiente antes

Posición actual antes

Rellenar celdas saltadas con línea horizontalSe propaga el estado de posición actual antes

- --[ ]-- - --[ ]--

Incluir símbolo interconexión ascendente

Figura 64. Esquema de progresión del tipo 7

5.15.3.8. Private Sub Sub_Tipo8VariablesdeProgreso()

Corresponde al elemento “Temporizador retentivo”.

A partir de ahora los elementos tipo 2, 3, 5 y 6 se comportan normalmente.

Un temporizador retentivo ocupa 4 columnas y 3 filas, por lo que la celda siguiente será la actual + 4 y no + 2 como los operandos anteriores.

Es necesario determinar el número más alto de elementos de la entrada “TIN” o “RESET”, para saber en que columna debe comenzar el timer.

En este caso no es necesario actualizar la variable global con el número de filas ocupadas, pues la actualización se realizó cuando se evaluó el elemento “bifurcación ascendente en T o X”.

Page 222: DCSLLL

5 Programación

221

5.15.3.9. Private Sub Sub_Tipo9VariablesdeProgreso() Corresponde al elemento “Contador”.

A partir de ahora los elementos tipo 2, 3, 5 y 6 se comportan normalmente.

Un contador ocupa 4 columnas y 3 filas, por lo que la celda siguiente será la actual + 4 y no + 2 como los operandos anteriores.

Es necesario determinar el número más alto de elementos de la entrada “CTU”, “CTD” o “RESET”, para saber en que columna debe comenzar el contador.

En este caso no es necesario actualizar la variable global con el número de filas ocupadas, pues la actualización se realizó cuando se evaluó el elemento “bifurcación ascendente en T o X”.

5.15.3.10. Private Sub Sub_Tipo10VariablesdeProgreso() Corresponde al elemento “Temporizador retardo”.

Se comporta básicamente igual que el tipo 4 (salida), excepto en que ocupa tres filas, por lo que la variable global que contiene el número de filas de la línea debe de ser al menos 3.

5.15.4. Procedimientos y funciones de acciones de datos

5.15.4.1. Private Sub Sub_Tipo1VariablesdeDatos(Str_Imagen As String) Agrupa los elementos de tipo operando con dirección a 1 bit, es decir, todos aquellos

que acceden a un registro de 1 bit.

Documentación y decisiones El parámetro Str_imagen contiene el nombre de la imagen que le corresponde al

elemento que ha llamado a la función, por lo que es directamente el campo “imagen” de la celda gráfica.

Hay que tener en cuenta que cuando hay un temporizador retentivo en la línea, el elemento de salida (hC4) no debe de sobrescribir la imagen con que inicializó el campo el temporizador.

Para rellenar los campos “texto” e “informacion” se van a utilizar dos funciones especializadas, ver procedimientos Fun_LeerCampoEtiquetaDireccion y Fun_LeerCamposEtiquetaDireccion.

Ya sólo queda rellenar el campo “estado”, para lo cual es necesario evaluar si el elemento está forzado o no, y si no lo está en el caso de estar simulándose un programa, el estado de la lógica.

Page 223: DCSLLL

5 Programación

222

Propagar estados forzados

Hay que tener en cuenta que al realizar las acciones de progresión, en algunos casos es necesario propagar el estado de una celda en otras.

Por ejemplo, si el elemento anterior estaba en la posición 14,0 y se evalúa un elemento de salida (posición 20,0), es necesario propagar el estado de la posición 14,0 a lo largo de la posición 15,0; 16,0; 17,0; 18,0 y 19,0. Si resulta que el elemento estaba forzado, es un error propagar este estado y no el estado lógico resultante.

Para solucionarlo es necesario que las cadenas de texto además de indicar si el elemento está forzado a ON u OFF, indiquen el estado de la lógica resultante para posteriormente poder extraerlo. Así, el campo estado puede tomar los siguientes valores:

• “Estado ON”

• “Estado OFF”

• “Estado ON Forzado ON”

• “Estado ON Forzado OFF”

• “Estado OFF Forzado ON”

• “Estado OFF Forzado OFF”

Flujograma Campo “imagen” inicializado?

No Rellenar campo “imagen” con el contenido de Str_imagen

Rellenar campo “texto” (Fun_LeerCampoEtiquetaDireccion)

Rellenar campo “informacion” (Fun_LeerCamposEtiquetaDireccion)

Elemento forzado

No Modo ejecución y campo “valor1bitdespues” = 1?

No Estado OFF

Si Estado ON

Si Forzado a ON

Si Modo ejecución y campo “valor1bitdespues” = 1?

No Estado OFF Forzado ON

Si Estado ON Forzado ON

No Modo ejecución y campo “valor1bitdespues” = 1?

No Estado OFF Forzado OFF

Si Estado ON Forzado OFF

Fin

5.15.4.2. Private Sub Sub_Tipo2VariablesdeDatos(Str_Imagen As String) Agrupa los elementos de tipo operando con dirección a 16 bits, es decir, todos aquellos

que acceden a un registro de 16 bits.

Page 224: DCSLLL

5 Programación

223

Es válido todo lo expuesto en el procedimiento anterior, excepto:

• Es necesario añadir el contenido del campo “Valor16bits” en el texto de la celda si se está en modo depuración.

5.15.4.3. Private Sub Sub_Tipo3VariablesdeDatos(Str_Imagen As String) Agrupa los elementos de tipo operando bit, es decir, todos aquellos que acceden a un bit

específico de un registro de 16 bits.

Documentación y decisiones El parámetro Str_imagen contiene el nombre de la imagen que le corresponde al

elemento que ha llamado a la función, por lo que es directamente el campo “imagen” de la celda gráfica.

Hay que decodificar el contenido del campo “parametro” del elemento para extraer la dirección del registro de 16 bits y la posición del bit deseado, de acuerdo a lo expuesto en el capítulo 4.2.3.5 Instrucciones de bit simple

Para rellenar los campos “texto” e “informacion” se van a utilizar dos funciones especializadas, ver procedimientos Fun_LeerCampoEtiquetaDireccion y Fun_LeerCamposEtiquetaDireccion.

Al no poder simular esta instrucción por no corresponder al set de instrucciones de los modelos de LM permitidos no es necesario evaluar el estado lógico.

Flujograma Rellenar campo “imagen” con el contenido de Str_imagen

Rellenar campo “texto” (Fun_LeerCampoEtiquetaDireccion)

Rellenar campo “informacion” (Fun_LeerCamposEtiquetaDireccion)

Estado OFF

Fin

5.15.4.4. Private Sub Sub_Tipo4VariablesdeDatos(Str_Imagen As String, Dbl_Resolucion As Double, Str_Resolucion As String)

Agrupa los elementos de tipo “Temporizador retardo a ON” y “Temporizador retardo a OFF”.

Ocupa tres celdas de la última columna (20).

Documentación y decisiones El parámetro Str_imagen contiene el nombre de la imagen que le

corresponde al elemento que ha llamado a la función, por lo que es directamente el campo “imagen” de la celda gráfica.

Como el tipo 4 de datos es común para los temporizadores retardo de las tres bases de tiempo, es necesario que al llamar a la función, se especifique con que base de tiempos se

Page 225: DCSLLL

5 Programación

224

tienen que representar los valores de los campos “Valor16bits” y “Valor16bitsPRS” mediante los parámetros siguientes:

• Dbl_Resolucion: Base de tiempo. Al multiplicar los valores de acumulador y preset se obtiene el tiempo correcto. Ejemplo: 1234 x 0,1 = 123,4 sg.

• Str_Resolucion: Formato de representación. Para presentar el tiempo obtenido en el formato correcto se utiliza la función de Visual Basic “Format” que requiere una cadena de texto indicando el formato deseado. Así 20 x 0,1 = 2 sg con un formato “0,0” se representará 2,0.

Celda 20,0

En la primera celda sólo es necesario inicializar el campo “imagen” con el parámetro Str_Imagen, pues del resto de campos se va a encargar el elemento de salida (hC4) asociado al temporizador con retardo.

Celda 20,1 – Preset

La segunda celda es similar al tipo 2 de datos, con las siguientes particularidades.

• El campo imagen se inicializa con una imagen en blanco, pues es texto todo lo que se muestra en la celda.

• La cadena de texto devuelta por la función Fun_LeerCampoEtiquetaDireccion se completa con las cadenas “PRS” y el valor del campo “Valor16bitsPRS” si se está en modo depuración.

Celda 20,2 – Acumulador

La segunda celda es similar al tipo 2 de datos, con las siguientes particularidades.

• El campo imagen se inicializa con una imagen en blanco, pues es texto todo lo que se muestra en la celda.

• La cadena de texto devuelta por la función Fun_LeerCampoEtiquetaDireccion se completa con las cadenas “ACC” y el valor del campo “Valor16bits” si se está en modo depuración.

5.15.4.5. Private Sub Sub_Tipo5VariablesdeDatos(Dbl_Resolucion As Double, Str_Resolucion As String)

Agrupa los elementos de tipo “Temporizador retentivo”.

Es válido todo lo expuesto en el procedimiento anterior, excepto en que:

• No es necesario el parámetro Str_Imagen que especifique la imagen a utilizar en cada caso, pues este tipo implementa únicamente el elemento “Temporizador retentivo”.

• Ocupa 3x3 celdas que deben de ser inicializadas.

• El temporizador retentivo al no trabajar asociado a un elemento de salida (hC4) debe de ser quien establezca el estado de la celda “OUT”, ver procedimiento Sub_Tipo1VariablesdeDatos.

5.15.4.6. Private Sub Sub_Tipo6VariablesdeDatos(Str_Imagen As String) Agrupa los elementos de tipo operando salto.

Page 226: DCSLLL

5 Programación

225

Es válido todo lo expuesto en el procedimiento Sub_Tipo1VariablesdeDatos, excepto:

• Al no trabajar con otros elementos asociados a la misma celda como ocurre en el caso de “Salida no retentiva” y “Temporizador retardo” no es necesario evaluar si la imagen de la celda ya ha sido inicializada.

• Las funciones que generan las cadenas de texto pasan a ser Fun_LeerCampoEtiquetaSalto y Fun_LeerCamposEtiquetaSalto.

5.15.4.7. Private Sub Sub_Tipo7VariablesdeDatos(Str_Imagen As String) Agrupa los elementos de tipo operador sin posibilidad de dirección de error.

Documentación y decisiones El parámetro Str_imagen contiene el nombre de la imagen que le corresponde al

elemento que ha llamado a la función, por lo que es directamente el campo “imagen” de la celda gráfica.

Tal y como se puede apreciar en la figura, no es necesario rellenar el campo texto, ni por tanto el campo información.

Ninguno de estos elementos puede ser forzado, por lo que para rellenar el campo “estado” sólo es necesario evaluar si se está en modo depuración el valor del campo “valor1bitdespues”.

Flujograma Rellenar campo “imagen” con el contenido de Str_imagen

Estado OFF

Modo ejecución y campo “valor1bitdespues” = 1?

Si Estado ON

Fin

5.15.4.8. Private Sub Sub_Tipo8VariablesdeDatos(Str_Imagen As String) Agrupa los elementos de tipo operador con posibilidad de dirección de error.

Documentación y decisiones

El parámetro Str_imagen contiene el nombre de la imagen que le corresponde al elemento que ha llamado a la función, por lo que es directamente el campo “imagen” de la celda gráfica.

Tal y como se comenta en el capítulo 4.2.3.11 Instrucciones matemáticas, es necesario evaluar el parámetro del elemento para diferenciar entre un operador sin dirección de error (valor h7FFF) o con (número de dirección).

Page 227: DCSLLL

5 Programación

226

Si se detecta que el elemento tiene dirección de error, para rellenar los campos “texto” e “informacion” se van a utilizar dos funciones especializadas, ver procedimientos Fun_LeerCampoEtiquetaDireccion y Fun_LeerCamposEtiquetaDireccion. Al no poder simular esta instrucción por no corresponder al set de instrucciones de los modelos de LM permitidos, no es necesario completar el campo “texto” con el contenido del registro si se está depurando.

Ninguno de estos elementos puede ser forzado, por lo que para rellenar el campo “estado” sólo es necesario evaluar si se está en modo depuración el valor del campo “valor1bitdespues”.

Flujograma Rellenar campo “imagen” con el contenido de Str_imagen

Dirección de error?

Si Rellenar campo “texto” (Fun_LeerCampoEtiquetaDireccion)

Rellenar campo “informacion” (Fun_LeerCamposEtiquetaDireccion)

Estado OFF

Modo ejecución y campo “valor1bitdespues” = 1?

Si Estado ON

Fin

5.15.4.9. Private Sub Sub_Tipo9VariablesdeDatos(Str_Imagen As String) Agrupa los elementos de tipo operando datos 1-8 bloques de 16 bits zona I/O (PULL).

Es válido todo lo expuesto en el procedimiento Sub_Tipo1VariablesdeDatos, excepto:

• Hay que decodificar el contenido del campo “parametro” del elemento de acuerdo a lo expuesto en el capítulo 4.2.3.9 Instrucciones de manipulación de datos.

• Ninguno de estos elementos puede ser forzado, por lo que para rellenar el campo “estado” sólo es necesario evaluar si se está en modo depuración el valor del campo “valor1bitdespues”.

5.15.4.10. Private Sub Sub_Tipo10VariablesdeDatos(Str_Imagen As String) Agrupa los elementos de tipo operando datos 1-8 bloques de 16 bits zona registros

(PULL).

Es válido todo lo expuesto en el procedimiento Sub_Tipo1VariablesdeDatos, excepto:

• Hay que decodificar el contenido del campo “parametro” del elemento de acuerdo a lo expuesto en el capítulo 4.2.3.9 Instrucciones de manipulación de datos.

• Ninguno de estos elementos puede ser forzado, por lo que para rellenar el campo “estado” sólo es necesario evaluar si se está en modo depuración del valor del campo “valor1bitdespues”.

Page 228: DCSLLL

5 Programación

227

5.15.4.11. Private Sub Sub_Tipo11VariablesdeDatos(Str_Imagen As String) Agrupa los elementos de tipo subrutina.

Documentación y decisiones El parámetro Str_imagen contiene el nombre de la imagen que le corresponde al

elemento que ha llamado a la función, por lo que es directamente el campo “imagen” de la celda gráfica.

Para rellenar los campos “texto” e “informacion” se van a utilizar dos funciones especializadas, ver procedimientos Fun_LeerCampoEtiquetaSubrutina y Fun_LeerCamposEtiquetaSubrutina.

Ninguno de estos elementos puede ser forzado, por lo que para rellenar el campo “estado” sólo es necesario evaluar si se está en modo depuración el valor del campo “valor1bitdespues”

Flujograma Rellenar campo “imagen” con el contenido de Str_imagen

Rellenar campo “texto” (Fun_LeerCampoEtiquetaSubrutina)

Rellenar campo “informacion” (Fun_LeerCamposEtiquetaSubrutina)

Estado OFF

Modo ejecución y campo “valor1bitdespues” = 1?

Si Estado ON

Fin

5.15.4.12. Private Sub Sub_Tipo12VariablesdeDatos(Str_Imagen As String) Agrupa los elementos de tipo constante.

Documentación y decisiones El parámetro Str_imagen contiene el nombre de la imagen que le corresponde al

elemento que ha llamado a la función, por lo que es directamente el campo “imagen” de la celda gráfica.

Al contener el parámetro únicamente el valor de la constante no hay que inicializar el campo información, pero si el campo “texto”.

Ninguno de estos elementos puede ser forzado, por lo que para rellenar el campo “estado” sólo es necesario evaluar si se está en modo depuración el valor del campo “valor1bitdespues”.

Flujograma

Rellenar campo “imagen” con el contenido de Str_imagen

Rellenar campo “texto” con el valor de la constante

Page 229: DCSLLL

5 Programación

228

Estado OFF

Modo ejecución y campo “valor1bitdespues” = 1?

Si Estado ON

Fin

5.15.4.13. Private Sub Sub_Tipo14VariablesdeDatos() Corresponde al elemento “Contador”.

Es válido todo lo expuesto en el procedimiento Sub_Tipo5VariablesdeDatos, excepto:

• Al no utilizar bases de tiempo no son necesarios los parámetros Dbl_resolucion y Str_Resolucion, pues el valor de los registros acumulador y preset son los valores a representar.

5.15.4.14. Private Sub Sub_Tipo15VariablesdeDatos() Corresponde al elemento “Constante en coma flotante”.

Documentación y decisiones No es necesario el parámetro Str_Imagen que especifique la imagen a utilizar en cada

caso, pues este tipo implementa únicamente el elemento “Constante en coma flotante”.

Al contener el parámetro únicamente el valor de la constante no hay que inicializar el campo información, pero si el campo “texto”. Tal y como se detalla en el capítulo 4.2.3.9 Instrucciones de manipulación de datos, hay que encadenar los campos “parametro” del elemento actual y del siguiente para extraer el valor real codificado.

Al no poder simular esta instrucción por no corresponder al set de instrucciones de los modelos de LM permitidos no es necesario evaluar el estado lógico.

Flujograma Rellenar campo “imagen” con la referencia a la imagen correspondiente

Leer elemento siguiente para obtener los cuatro bytes necesarios

Rellenar campo “texto” con el valor de la constante

Estado OFF

Fin

5.15.4.15. Private Sub Sub_Tipo16VariablesdeDatos() Corresponde al elemento “Lectura de datos tabla estados del sistema (PULS)”.

Es válido todo lo expuesto en el procedimiento Sub_Tipo1VariablesdeDatos, excepto:

Page 230: DCSLLL

5 Programación

229

• No es necesario el parámetro Str_Imagen que especifique la imagen a utilizar en cada caso, pues este tipo implementa únicamente el elemento “Lectura de datos tabla estados del sistema (PULS)”.

• Hay que decodificar el contenido del campo “parametro” del elemento de acuerdo a lo expuesto en el capítulo 4.2.3.9 Instrucciones de manipulación de datos.

• Al no poder simular esta instrucción por no corresponder al set de instrucciones de los modelos de LM permitidos no es necesario evaluar el estado lógico.

5.15.4.16. Private Sub Sub_Tipo17VariablesdeDatos() Corresponde al elemento “Salto a subrutina”.

Documentación y decisiones No es necesario el parámetro Str_Imagen que especifique la imagen a utilizar en cada

caso, pues este tipo implementa únicamente el elemento “Salto a subrutina”.

Tal y como se detalla en el capítulo 4.2.3.8 Instrucciones de referencia de memoria, hay que añadir los campos “parametro” del elemento actual y del siguiente para obtener los datos necesarios.

Para rellenar los campos “texto” e “informacion” se van a utilizar dos funciones especializadas, ver procedimientos Fun_LeerCampoEtiquetaSubrutina y Fun_LeerCamposEtiquetaSubrutina.

Ninguno de estos elementos puede ser forzado, por lo que para rellenar el campo “estado” sólo es necesario evaluar si se está en modo depuración el valor del campo “valor1bitdespues”

Flujograma Rellenar campo “imagen” con la referencia a la imagen correspondiente

Leer elemento siguiente para obtener los cuatro bytes necesarios

Rellenar campo “texto” (Fun_LeerCampoEtiquetaSubrutina)

Rellenar campo “informacion” (Fun_LeerCamposEtiquetaSubrutina)

Estado OFF

Modo ejecución y campo “valor1bitdespues” = 1?

Si Estado ON

Fin

5.15.4.17. Private Sub Sub_Tipo18VariablesdeDatos()

Corresponde al elemento “Marcador comentario de línea”.

Una vez obtenido el número de comentario codificado en el campo “parámetro”, se

rellenan los campos “texto” e “información” de la celda 0,0.

Page 231: DCSLLL

5 Programación

230

El texto a escribir en el campo “texto” es el número de comentario encerrado entre paréntesis.

El texto a escribir en el campo “informacion” sigue la siguiente estructura:

--COMENTARIO—

Campo “Texto”

Flujograma Rellenar campo “texto”

Leer reg. comentario de línea (Fun_LeerRegistroComentarioLineaPorNumero)

Rellenar campo “informacion”

Fin

5.15.5. Procedimientos y funciones auxiliares

5.15.5.1. Private Sub Sub_InterconexionAntesTAbierta() Rellena la celda de interconexión anterior a la actual con una imagen de interconexión

en T abierta.

Utiliza el campo “Valor1bitantes” del elemento actual para inicializar el campo estado

si se está en modo depuración.

5.15.5.2. Private Sub Sub_InterconexionAntesTCerrada() Rellena la celda de interconexión anterior a la actual con una imagen de interconexión

en T cerrada.

Utiliza el campo “Valor1bitantes” del elemento actual para inicializar el campo estado

si se está en modo depuración.

5.15.5.3. Private Sub Sub_InterconexionAntesX() Rellena la celda de interconexión anterior a la actual con una imagen de interconexión

en X.

Utiliza el campo “Valor1bitantes” del elemento actual para inicializar el campo estado

si se está en modo depuración.

5.15.5.4. Private Sub Sub_RellenaAntesGuion(Int_Fila As Integer, Optional Bool_Despues As Boolean)

Localiza la última celda inicializada anterior a la celda actual de la fila indicada y dibuja una línea horizontal hasta la celda actual, propagando el estado de la celda anterior.

En el capítulo 5.15.4 Sub_Tipo1VariablesdeDatos se detalla que en el caso de que en la celda anterior exista un elemento forzado, el contenido del campo “estado” incluiría el

Page 232: DCSLLL

5 Programación

231

estado de la lógica subyacente, por ejemplo “Estado ON Forzado ON”, por lo que sólo es necesario eliminar la cadena “Forzado ON” para obtener el estado a propagar.

5.15.5.5. Private Function Fun_LeerCampoEtiquetaDireccion(Int_Numero As Integer) As String

Esta función es llamada por aquellos elementos cuyo parámetro corresponde a la dirección de un registro de la tabla de memoria de usuario.

Devuelve la cadena de texto a escribir en el campo “texto” de la celda ocupada por el elemento, así crea la siguiente estructura:

Campo “Etiqueta”

Número de dirección

Si se tiene que mostrar el valor del registro por estarse en modo de depuración, éste debe de ser añadido posteriormente.

Flujograma Leer reg. etiqueta de dirección (Fun_LeerRegistroEtiquetaDireccionPorNumero)

Crear cadena de texto: Etiqueta + Return + Numero de dirección

Devuelve la cadena de texto creada

Fin

IDEM para procedimiento:

• Private Function Fun_LeerCampoEtiquetaSalto(Int_Numero As Integer) As String

• Private Function Fun_LeerCampoEtiquetaSubrutina(Int_Numero As Integer) As String

5.15.5.6. Private Function Fun_LeerCampoEtiquetaBit(Lng_Parametro As Long) As String

Es válido todo lo expuesto en el procedimiento anterior, excepto en que al tratarse de un elemento cuyo parámetro corresponde a un bit, es necesario primero decodificar el parámetro recibido, en el número de registro y la posición del bit, de acuerdo a lo expuesto en el apartado 4.2.3.5 Instrucciones de bit simple, para poder crear la cadena de texto con la siguiente estructura:

Campo “Etiqueta”

Número de dirección – Número posición del bit

5.15.5.7. Private Function Fun_LeerCamposEtiquetaDireccion(Int_Numero As Integer) As String

Esta función es llamada por aquellos elementos cuyo parámetro corresponde a la dirección de un registro de la tabla de memoria de usuario.

Devuelve la cadena de texto a escribir en el campo “información” de la celda ocupada por el elemento, formando la siguiente estructura:

--ETIQUETA--

Campo “Etiqueta”

Campos “DescrN1” “DescrN2” “DescrN3”

Page 233: DCSLLL

5 Programación

232

--COMENTARIO—

Campo “Texto”

Flujograma Leer reg. etiqueta de dirección (Fun_LeerRegistroEtiquetaDireccionPorNumero)

Existe registro?

Si Crear primera parte de la cadena de texto

Leer reg. comentario de dirección (Fun_LeerRegistroComentarioDireccionPorNumero)

Si Crear segunda parte de la cadena de texto

Devuelve la cadena de texto creada

Fin

5.15.5.8. Private Function Fun_LeerCamposEtiquetaBit(Lng_Parametro As Long) As String

Es válido todo lo expuesto en el procedimiento anterior, excepto en que al tratarse de un elemento cuyo parámetro corresponde a un bit, es necesario primero decodificar el parámetro recibido, en el número de registro y la posición del bit, de acuerdo a lo expuesto en el apartado 4.2.3.5 Instrucciones de bit simple, para poder crear la cadena de texto.

5.15.5.9. Private Function Fun_LeerCamposEtiquetaSalto(Int_Numero As Integer) As String

Es válido todo lo expuesto en el procedimiento anterior, excepto en que al tratarse de un elemento cuyo parámetro es un salto, no existe un archivo de documentación de comentarios de salto, por lo que sólo se tiene en cuenta la etiqueta.

IDEM para procedimiento:

• Private Function Fun_LeerCamposEtiquetaSubrutina(Int_Numero As Integer) As String

5.15.5.10. Function Fun_MayorColumnaOcupada() As Integer Evalúa las tres filas primeras y devuelve el número de la columna ocupada más a la

derecha en cualquiera de ellas.

Esta función se utiliza para calcular la posición de comienzo de los elementos “Timer retentivo” y “Contador”, que tienen elementos de entrada en las filas 0 y 2 ó 0, 1 y 2 respectivamente.

5.15.5.11. Function Fun_ExisteTimerRetentivo() As Boolean Evalúa todos los elementos que componen la línea y devuelve verdadero si existe un

temporizador retentivo en la línea actual.

• Timer retentivo base 1 sg: código h4E.

• Timer retentivo base 0,1 sg: código h4D.

• Timer retentivo base 0,01 sg: código h6C.

Page 234: DCSLLL

5 Programación

233

5.15.5.12. Function Fun_ExisteContador() As Boolean Evalúa todos los elementos que componen la línea y devuelve verdadero si existe un

contador (código h4F) en la línea actual.

Page 235: DCSLLL

5 Programación

234

5.16. Módulo de soporte tablas internas (Mdl_TablasInternas) Librería de procedimientos para crear, borrar y editar datos de las tablas internas que

contienen la información del proyecto abierto.

En los capítulos 5.3 ¿Bases de datos o tablas en memoria interna? y 5.10.1.2 Evolución de las direcciones, se decidió que los datos a guardar en tablas corresponden a:

• Archivo de configuración

• Programa

• Mapeado de memoria

• Evolución salidas

5.16.1. Documentación y decisiones En los siguientes apartados se expone que formato se ha elegido para cada uno de los

tipos de datos en función de las necesidades.

5.16.1.1. Generalidades de las tablas En Visual Basic se puede trabajar con:

• Tablas fijas: Tienen siempre el mismo tamaño.

• Tablas dinámicas: Pueden aumentar o reducir el número de registros para adaptarse a las necesidades y a los recursos de memoria del sistema.

Para ahorrar recursos, siempre que el número de registros sea variable, se va a trabajar con tablas dinámicas.

Una tabla dinámica ha de tener como mínimo un registro. Para que el número de registros coincida con el índice superior es mejor que el registro de índice 0 no se utilice si es posible.

5.16.1.2. Archivo de configuración En el capítulo 4.6.1 Codificación y estructura del fichero *.cfg, se determina que cada

parámetro del archivo es una cadena de texto.

Se ha optado por un tabla fija de 1 a 66 registros.

Campos:

• “Numero”: Entero

• “Contenido”: String (cadena de texto)

5.16.1.3. Programa En el apartado 4.2.1 Estructura básica del fichero *.ldr, se determina que el fichero de

código de programa (*.ldr) se compone de 11 partes diferenciables.

De acuerdo al capítulo 5.9.1.1 Separar las líneas, la parte número 10 que codifica las líneas de programa, debe de ser evaluada separando las líneas en registros independientes para facilitar la visualización y simulación.

Por ello, se van a implementar dos tablas: Una con las líneas de programa y otra con las diez partes restantes.

Page 236: DCSLLL

5 Programación

235

Partes de programa Al igual que en el caso de los parámetros de configuración, se va a utilizar una tabla fija

de 10 registros.

Al estar estas partes codificadas tanto en cadenas de texto como en código hexadecimal y teniendo longitudes muy diferentes, se ha optado por utilizar el tipo de variable “Variant” y no la cadena de texto habitual. El tipo “Variant” puede almacenar cualquier tipo de datos aunque a costa de ocupar un poco más.

Campos:

• “Numero”: Entero

• “Contenido”: Variant

Líneas de programa Para guardar las líneas se va a utilizar una tabla dinámica de 0 a N líneas (el registro 0

no se utiliza), donde cada registro a parte de los campos con el número de línea y la tabla de registros donde almacenar cada uno de los elementos, debe de tener el campo “HaSidoSaltada” de acuerdo al apartado 5.15.1.2 Relación entre el módulo de simulación y el de visualización.

El campo “HaSidoSaltada” puede tomar los valores 0, 1 ó 2, por lo que el tipo de datos que más se ajusta es el tipo Byte (rango 0-255).

Así los campos finalmente son:

• “Numero”: Long.

• “HaSidoSaltada”: Byte.

• “Elementos”: Tabla dinámica donde cada registro es un elemento.

Elementos

Si se juntan las necesidades de los capítulos 5.14.1.1 Definición del registro línea y 5.15.1.2 Relación entre el módulo de simulación y el de visualización, los campos del registro elemento son:

• “Opcode”: String

• “Parámetro”: String

• “BitHistorico”: Byte

• “BitForzado”: Byte

• “Valor1bitAntes”: Byte

• “Valor1bitDespues”: Byte

• “Valor16bits”: Long

• “Valor16bitsPRS”: Long

Para guardar los valores lógicos, en vez de seleccionar el tipo “boolean” que ocupa dos bytes en memoria, se ha escogido el tipo “Byte” pues ocupa un solo byte y permite las mismas opciones que el tipo “Boolean” con la siguiente diferencia, el negado (Not) de una variable tipo byte de valor 1 es -1, por lo que no se debe de utilizar la instrucción “If Not variable” si no la instrucción “If variable =0”.

Page 237: DCSLLL

5 Programación

236

Para guardar los valores de 16 bits, si se considera que se trata de un valor entero de 16 bits sin signo (rango 0 a 65535) es necesario utilizar el tipo “Long” (4 Bytes, rango - 2.147.483.648 a 2.147.483.647) pues el tipo “Integer” no es suficiente (rango -32.768 a 32767)

5.16.1.4. Mapeado de memoria Si se tienen en cuenta todos los modelos del apartado 4.6.2 Mapeado de memoria, se

observa que:

• El área de memoria de sistema en el mayor de los casos es 0-4095.

• El área de memoria de usuario en el mayor de los casos es de 0-8191.

• El área de memoria de programa en el mayor de los casos es de 0-32767.

El área de memoria de programa es la que almacena las líneas de programa, parte ésta tratada en el apartado anterior.

Tabla - Área de memoria de usuario

1 BITENT.

T ABLA DEEST ADOS E/S(E/S FISICAS)

T ABLA DEEST ADOS E/S

(BOBINASINT ERNAS)

T ABLA DEREGIST ROS

1 BITSAL. 16 BIT S

Figura 65. Memoria de usuario

El área de memoria de usuario se divide en tres zonas:

• Entradas/Salidas físicas de 1 bit.

• Bobinas internas de 1 bit.

• Registros de 16+1 bits.

Se puede trabajar con tablas diferentes para cada una de las zonas, o por el contrario con una global con un tipo de dato capaz de albergar a cualquiera.

Para evitar trabajar con tres tablas de memoria de usuario, se va a implementar una sola con tres campos en cada registro.

Page 238: DCSLLL

5 Programación

237

Velocidad de acceso

Cuando mayor velocidad se necesita es durante la simulación, momento en el que el programa tiene que leer y escribir en cualquier dirección de la forma más rápida posible para reducir el tiempo total de simulación.

Esta velocidad no es necesaria si el usuario está visualizando o editando los registros en el formulario correspondiente.

Es por ello que se decide trabajar con tablas de registros continuos desde 0 hasta el número máximo en función de la configuración de sistema seleccionada. Así se consigue:

• El acceso al registro es directo, la dirección 4095 estará en la posición 4095. Se consigue la velocidad deseada en lectura y escritura.

• Los objetos de visualización deben de ocultar aquellos registros intermedios que no correspondan al mapeado actual. Se hace más lento el proceso, pero no es crítico.

• Al utilizar tablas dinámicas que adaptan el tamaño a la configuración del sistema se reduce el número de registros necesario reduciendo el tamaño en memoria. Las tablas se deben de crear en el momento que se establezca un nuevo mapeado de memoria, ya sea por carga del fichero de configuración, o edición del mismo.

Campos

De acuerdo al capítulo 5.10.1.2 Evolución de las direcciones se deben de añadir los dos últimos campos a los ya estudiados, quedando el registro formado por los siguientes campos:

• “Numero”: Entero

• “Contenido1bE”: Byte

• “Contenido1bS”: Byte

• “Contenido16b”: Long

• “GuardarEvolucion”: Boolean

• “IndiceEvolucion”: Entero

Tabla - Área de memoria de sistema Éste área se compone de datos de 8 bits.

Aunque podría implementarse con una tabla fija de 0-4095 registros, se va a utilizar una tabla dinámica para poder liberar espacio si no hay un proyecto cargado.

Campos:

• “Numero”: Entero

• “Contenid8b”: Entero

5.16.1.5. Evolución de salidas

De acuerdo al capítulo 5.10.1.2 Evolución de las direcciones se ha optado por una tabla dinámica.

Campos:

• “Numero”: Entero

Page 239: DCSLLL

5 Programación

238

• “Binomios”: Tabla dinámica de registros con campos:

- “Tiempo”: Long

- “Valor”: Byte

5.16.2. Variables globales Con_Programa(1 to 66): Contiene los datos del archivo configuración

Par_Programa(1 To 10): Contiene las partes del archivo programa.

Lin_Programa(): Contiene las líneas de programa.

MemU_Usuario(): Contiene los datos del área memoria de usuario.

MemS_Sistema(): Contiene los datos del área de memoria de sistema.

Evo_Salida1b(): Contiene los binomios (tiempo-valor) de evolución de direcciones.

Map_Memoria: Contiene los datos de la configuración del mapeado de memoria.

5.16.3. Procedimientos y funciones

5.16.3.1. Public Sub Sub_InicializarTablas() Procedimiento que inicializa todas las tablas a cero. Se usa tanto a la hora de abrir el

proyecto para partir de tablas vacías, como a la hora de cerrarlo para liberar memoria.

Flujograma Inicializar tablas dinámicas a cero registros

Borrar configuración mapeado de memoria (Map_Memoria)

Borrar datos de tablas fijas

Fin

5.16.3.2. Public Sub Sub_EscribirRegistroConfiguracion(Con_Actual As Configuracion) Escribe el registro de parámetro de configuración recibido en la tabla interna.

Al ser una tabla fija con tantas posiciones como parámetros de configuración a guardar la asignación es inmediata.

Flujograma Escribir registro en tabla interna (Con_Programa)

Fin

IDEM para procedimiento:

• Public Sub Sub_EscribirRegistroPartePrograma(Par_Actual As Parte)

5.16.3.3. Public Sub Sub_EscribirRegistroLineaPrograma(Lin_Actual As Linea) Escribe el registro de línea de programa recibido en la tabla interna.

Tal y como se ha diseñado la tabla dinámica, la correspondencia número-posición es inmediata (la dirección 10 corresponde a la posición 10 de la tabla).

Documentación y decisiones Esta función debe de editar y añadir en función de si el número de la línea recibida

existe o no. Si se consulta el capítulo 5.14 Módulo de soporte para separar líneas de *.ldr (Mdl_SepararLineas), se aprecia que no es suficiente con añadir el nuevo registro

Page 240: DCSLLL

5 Programación

239

parametrizado al final de la tabla dinámica existente cada vez que se separa una nueva línea, ya que cuando se evalúan los parámetros de temporizadores y contadores, lo que se hace es completar los datos de una línea separada con anterioridad.

Flujograma Existe registro con mismo número

No Añadir nuevo registro al final de la tabla (Lin_Programa)

Si Editar registro existente (Lin_Programa)

Fin

5.16.3.4. Public Sub Sub_EscribirRegistroMemoriaUsuario(MemU_Actual As MemoriaUsuario)

Escribe el registro de memoria de usuario recibido en la tabla interna.

Aunque es una tabla dinámica, no es necesario aumentar el tamaño para incluir el nuevo registro, pues el dimensionado de la tabla se realiza a la hora de abrir el proyecto cuando se determina la configuración del sistema, o cuando se cambia ésta en el formulario de configuración.

Tal y como se ha diseñado la tabla dinámica, la correspondencia número-posición es inmediata (la dirección 10 corresponde a la posición 10 de la tabla).

Flujograma Escribir registro en tabla interna (MemU_Usuario)

Fin

IDEM para procedimiento:

• Public Sub Sub_EscribirRegistroMemoriaSistema(MemS_Actual As MemoriaSistema)

5.16.3.5. Public Function Fun_LeerRegistroConfiguracion(Int_Numero As Integer) As Configuracion

Devuelve el registro de parámetro de configuración almacenado en la tabla interna que corresponde al número de parámetro solicitado.

Al ser una tabla fija con tantas posiciones como parámetros de configuración, el número de parámetro coincide con la posición en la tabla.

Flujograma

Leer registro en tabla interna en la posición Int_Numero (Con_Programa)

Fin

IDEM para procedimiento:

• Public Function Fun_LeerRegistroPartePrograma(Int_Numero As Integer) As Parte

5.16.3.6. Public Function Fun_LeerRegistroLineaPrograma(Lng_Numero As Long) As Linea

Devuelve el registro de línea de programa almacenado en la tabla interna que corresponde al número de línea solicitada.

Page 241: DCSLLL

5 Programación

240

Tal y como se ha diseñado la tabla dinámica, la correspondencia número-posición es inmediata (la dirección 10 corresponde a la posición 10 de la tabla).

Flujograma Leer registro en tabla interna en la posición Lng_Numero (Lin_Programa)

Fin

IDEM para procedimientos:

• Public Function Fun_LeerRegistroMemoriaUsuario(Int_Numero As Integer) As MemoriaUsuario

• Public Sub Public Function Fun_LeerRegistroMemoriaSistema(Int_Numero As Integer) As MemoriaSistema

5.16.3.7. Public Function Fun_NRegistrosLineasPrograma() As Long Devuelve número de registros de líneas de programa de de la tabla interna.

Tal y como se ha diseñado la tabla dinámica (1 a N), el número de registros coincide con el índice superior de la tabla.

Flujograma Devolver índice superior actual de la tabla interna (Lin_Programa)

Fin

IDEM para procedimientos:

• Public Function Fun_NRegistrosMemoriaUsuario() As Integer

• Public Function Fun_NRegistrosMemoriaSistema() As Integer

5.16.3.8. Public Sub Sub_DimensionarTablasMapeadodeMemoria() Dimensiona las tablas memoria de usuario y de sistema en función de las opciones de

memoria configuradas, e inicializa la variable global Map_Memoria con los valores configurados.

Documentación y decisiones Si se consulta el apartado 4.6.2 Mapeado de memoria, se determina que los límites de la

zona de memoria de usuario dependen de los parámetros de configuración del sistema:

• N - Número de direcciones zona de E/S (parámetro nº: 33)

• Número de direcciones zona de registros (parámetro nº: 32)

• Modelo de procesador (parámetro nº: 25): Determina límites zona bobinas internas 1 bit (consultar Tabla 27. Mapeado de memoria)

Page 242: DCSLLL

5 Programación

241

Figura 66. Mapeado de memoria zona memoria de usuario

Flujograma Leer número de direcciones zona E/S (Fun_LeerRegistroConfiguracion)

Leer número de direcciones zona de registros (Fun_LeerRegistroConfiguracion)

Leer modelo de procesador (Fun_LeerRegistroConfiguracion)

Según modelo de procesador determinar número de direcciones zona bobinas 1 bit

0, 1, 6 Número de direcciones zona bobinas 1 bit = 767

IDEM para resto de modelos

Dimensionar tabla de memoria de usuario (MemU_Usuario)

Inicializar campo “Numero” de todos los registros de la tabla de memoria de usuario con la dirección correspondiente (MemU_Usuario)

Dimensionar tabla de memoria de sistema a 4096 direcciones (MemS_Sistema)

Inicializar campo “Numero” de todos los registros de la tabla de memoria de sistema con la dirección correspondiente (MemS_Sitema)

Actualizar formularios relacionados con el nuevo mapeado (Sub_ActualizarFormconMapeadoMemoria)

Fin

5.16.4. Procedimientos y funciones de ejecución rápida Con las funciones anteriores, para leer o modificar el valor de un campo de las tablas de

memoria es necesario acceder al registro completo. Para evitar perder tiempo durante la simulación, se han desarrollado las siguientes funciones que acceden únicamente al campo deseado en cada momento.

5.16.4.1. Public Sub Sub_BorrarMemoriadeUsuario() Este procedimiento es ejecutado cuando se comienza una nueva simulación.

E/S reales 1 bit

Bobinas internas

1 bit

Registros internos 16 bits

0 -

Par.33 - 1 -

4096 -

4096 + Par.32 - 1 -

Función(Par.25) -

Page 243: DCSLLL

5 Programación

242

Borra el contenido de los campos que contienen los valores de 1 bit de entrada y salida y de 16 bits, para eliminar los datos de simulaciones anteriores.

Flujograma Borrar contenido 1 bit de entrada (MemU_Usuario)

Borrar contenido 1 bit de salida (MemU_Usuario)

Borrar contenido 16 bit (MemU_Usuario)

… Repetir los tres últimos pasos con todos los registros de la tabla

Fin

5.16.4.2. Public Sub Sub_EscribirRegistroMemUContenido1bE(Int_Direccion As Integer, Byt_Valor As Byte)

Este procedimiento es ejecutado cuando se realiza una exploración de los estados de entrada y se ha producido un cambio en alguna dirección.

Escribe el valor recibido en el campo “Contenido1bE” del registro con la dirección indicada de la tabla de memoria de usuario.

De acuerdo al capítulo 5.10.1.2 Evolución de las direcciones, al ejecutarse este procedimiento cuando se está simulando el programa, es necesario guardar los cambios que se produzcan en la dirección si ésta ha sido seleccionada por el usuario, introduciendo un nuevo grupo (tiempo, valor) sólo si el valor a introducir es diferente del grupo anterior para de esta forma ahorrar memoria.

El valor que se debe de guardar es el valor resultado de realizar una OR entre el valor contenido en la tabla de estados de entradas y el de la tabla de estados de salidas.

Flujograma Escribir campo “Contenido1bE” en el registro de la tabla (MemU_Usuario)

Hay que guardar la evolución de este registro?

Si Recuperar indice del registro de la dirección en la tabla de evolución

Valor a guardar = OR de los campos “contenido1E” y “contenido1bS”

Valor del ultimo binomio distinto al valor a guardar?

Si Guardar nuevo binomio (tiempo actual, valor a guardar)

Fin

5.16.4.3. Public Sub Sub_EscribirRegistroMemUContenido1bS(Int_Direccion As Integer, Byt_Valor As Byte)

Este procedimiento es ejecutado cuando se ejecuta una línea de programa con un elemento de salida binario.

Escribe el valor recibido en el campo “Contenido1bS” del registro con la dirección indicada de la tabla de memoria de usuario y guarda la evolución de la dirección si ésta ha sido seleccionada por el usuario en el módulo de simulación, de igual forma que el procedimiento anterior.

Flujograma

Escribir campo “Contenido1S” en el registro de la tabla (MemU_Usuario)

Page 244: DCSLLL

5 Programación

243

Hay que guardar la evolución de este registro?

Si Recuperar indice del registro de la dirección en la tabla de evolución

Valor a guardar = OR de los campos “contenido1E” y “contenido1bS”

Valor del ultimo binomio distinto al valor a guardar?

Si Guardar nuevo binomio (tiempo actual, valor a guardar)

Fin

5.16.4.4. Public Sub Sub_EscribirRegistroMemUContenido16b(Int_Direccion As Integer, Lng_Valor As Long)

Escribe el valor recibido en el campo “Contenido16b” del registro con la dirección indicada de la tabla de memoria de usuario.

IDEM para procedimientos:

• Public Sub Sub_EscribirRegistroMemSContenido8b(Int_Direccion As Integer, Int_Valor As Integer)

5.16.4.5. Public Function Fun_LeerRegistroMemUContenido1b(Int_Numero As Integer) As Byte

Durante todas las referencias al mapeado de memoria, se ha explicado que durante la ejcución, el valor leído por el procesador de la tabla de estados E/S es la OR de los contenidos de la tabla de estados de entradas y de la tabla de estados de salida.

Este procedimiento realiza la OR de los campos “Contenido1bE” y “Contenido1bS” del registro de la tabla memoria de usuario con la dirección indicada y devuelve el valor resultante.

5.16.4.6. Public Function Fun_LeerRegistroMemUContenido16b(Int_Numero As Integer) As Long

Devuelve el valor del campo “Contenido16b” del registro con la dirección indicada de la tabla de memoria de usuario.

IDEM para procedimientos:

• Public Function Fun_LeerRegistroMemSContenido8b(Int_Numero As Integer) As Integer

5.16.4.7. Public Sub Sub_CrearTablaEvolucionSalidas() Este procedimiento es ejecutado cada vez que se inicia una nueva simulación.

Crea los registros en la tabla donde guardar la evolución de las direcciones de salida seleccionadas en el formulario de simulación.

Básicamente recorre todas las direcciones de la memoria de usuario y si tiene marcado el campo “GuardarEvolucion” crea un nuevo registro en la tabla, escribiendo el primer binomio con el valor para tiempo 0 us. Posteriormente, escribe el índice del nuevo registro en el campo “IndiceEvolucion” del registro de la tabla de memoria de usuario.

5.16.4.8. Public Function Fun_LeerRegistroEvolucionSalida1b(Int_NDireccion As Integer) As EvolucionSalida1b

Devuelve el registro de evolucion de salida correspondiente a la direccion indicada.

Page 245: DCSLLL

5 Programación

244

Si no existe devuelve un registro con el campo con el número de dirección igual a -1 y 0 binomios de evolución.

Flujograma Leer registro memoria de usuario (Fun_LeerRegistroMemoriaUsuario)

Existe registro en la tabla de evolución de salidas?

Si Devolver registro

No Devolver registro vacio

Fin

5.16.5. Procedimientos y funciones representación gráfica

5.16.5.1. Public Sub Sub_InicializarEstadosLineas() Este procedimiento es ejecutado cuando se reinicia una simulación, para no mantener

los datos de una simulación anterior.

Recorre todos los registros de la tabla de líneas del programa y borra los valores de los campos que guardan los datos de la simulación.

• “HaSidoSaltada” a 0.

• “Elementos”:

- “Valor16bits” a 0.

- “Valor16bitsPRS” a 0.

- “Valor1bitAntes” a 0.

- “Valor1bitDespues” a 0.

5.16.5.2. Public Sub Sub_InicializarEstadosLinea(Lng_NLinea As Long) Este procedimiento es ejecutado antes de simular una nueva línea, para no mantener los

datos de una simulación anterior en caso de que la línea sea saltada.

Realiza las mismas acciones que las descritas en el procedimieno anterior, pero sólo en la línea indicada.

5.16.5.3. Public Sub Sub_InicializarEstadosLineaSaltada(Lng_NLinea As Long) Este procedimiento es ejecutado cuando la línea ha sido saltada por un salto NSKR del

rango 8192-8447, para no mantener los datos de una simulación anterior en las líneas saltadas.

Modifica los campos siguientes de la línea indicada.

• “HaSidoSaltada” a 1 para indicar línea saltada.

• “Elementos”:

- “Valor16bits” a 0.

- “Valor16bitsPRS” a 0.

- “Valor1bitAntes” a 0.

- “Valor1bitDespues” a 0.

Page 246: DCSLLL

5 Programación

245

5.17. Módulo de soporte para bases de datos (Mdl_BasesdeDatos) Librería de procedimientos para crear y editar datos de las tablas de la base de datos con

la información de los archivos de documentación y las expresiones de evolución deseada de las entradas al sistema.

Estos archivos son:

• *.lbl - Address_label – Etiquetas de direcciones

• *.ace - Address_comment – Comentarios de direcciones

• *.lce - Line_comment - Comentarios de líneas de programa

• *.skp - Skip_label – Etiquetas de líneas de salto

• *.jsr - Subroutine_label – Etiquetas de líneas de subrutina

• *.bce - Bit_Comment – Comentarios de bit

• *.blb - Bit_label – Etiquetas de bit

5.17.1. Documentación y decisiones

5.17.1.1. Archivos de documentación Tal y como se justifica en el apartado 5.3 ¿Bases de datos o tablas en memoria interna?,

los datos de los archivos de documentación se guardan en una base de datos temporal, correspondiéndole a cada uno una tabla.

En el capítulo 4.3 F3 – Documentation functions se determina que existen dos tipos de ficheros de documentación: etiquetas y comentarios. Cada tipo requiere campos diferentes.

Tablas de etiquetas Así los campos a crear son:

• “NUMERO”: Long.

• “ETIQUETA”: String (cadena de texto) (7 caracteres).

• “DESCRN1”: String (9 caracteres).

• “DESCRN2”: String (9 caracteres).

• “DESCRN3”: String (9 caracteres).

Para transferir los datos, las funciones que leen y escriben estos registros van a trabajar con un nuevo tipo de variable compleja con los mismos campos. En el peor de los casos, etiquetas de bit, pueden existir hasta 65535 registros por lo que es necesario utilizar campos numéricos del tipo “Long” (entero largo - codificación de enteros con signo en 32 bits).

Tablas de comentarios Los campos a crear son:

• “NUMERO”: Long

• “CONTENIDO”: String

Para transferir los datos, las funciones que leen y escriben estos registros van a trabajar con un nuevo tipo de variable compleja con los mismos campos. En el peor de los casos,

Page 247: DCSLLL

5 Programación

246

comentarios de bit, pueden existir hasta 65535 registros por lo que es necesario utilizar campos numéricos del tipo “Long”.

Tal y como se aprecia, sólo existe un campo para recibir las 20 posibles líneas que conforman cada comentario. Es por eso, que las funciones de decodificación deben de concatenar todas las líneas en una sola.

5.17.1.2. Expresiones de evolución En el apartado 5.10.1.2 Evolución de las direcciones se enumeran los campos que deben

de formar esta tabla:

• “NUMERO”: Long

• “1b ENTRADA”: Memo

• “1b SALIDA”: Memo

• “16b E/S”: Memo

El tipo de datos que en Microsoft Access permite almacenar cadenas de texto de mas de 255 caracteres es el tipo “Memo”, mientras que la variable compleja de transferencia de datos entre funciones utiliza el tipo “String”.

5.17.1.3. Acceso a datos Para acceder mediante programación a los registros de una tabla de una base de datos,

Visual Basic utiliza los objetos Recordset. Estos permiten acceder a todos los registros de una tabla (modo “dbOpenTable”) o sólo a aquellos que cumplan ciertas condiciones (modo “dbOpenDynaset”).

El formulario Frm_MDIChildDocumentacion utiliza los controles de acceso a datos “Data” para acceder a cada una de las tablas, sin embargo al trabajar con bases de datos de Access 2000 el control no reconoce el formato de la base de datos si se intenta conectar directamente especificando la ruta de la base de datos y el nombre de la tabla, por ello, la conexión se realiza mediante un Recordset conectado previamente.

Si el control Data utilizase el mismo Recordset que las funciones de lectura y escritura programadas en el código, el control DBGrid asociado al objeto Data reflejaría en todo momento las operaciones realizadas por las funciones, por ello, se van a crear dos recordsets por cada una de las tablas, uno dedicado al control Data y otro para funciones.

5.17.2. Procedimientos y funciones

5.17.2.1. Variables globales Str_CaminoMDB: Almacena la ruta y nombre de la base de datos temporal.

Dbs_slm: Controla la conexión a la base de datos.

Rst_EtiDir: Controla la conexión a la tabla de etiquetas de dirección (Data).

Rst_EtiDir2: Controla la conexión a la tabla de etiquetas de dirección (Funciones).

IDEM para el resto de tablas.

5.17.2.2. Public Sub Sub_CrearBasedeDatos() Crea la base de datos donde guardar datos de documentación.

Aunque en una evolución normal del programa al salir del mismo se borra el archivo con la base de datos temporal, podría ser que por alguna excepción se abortase el programa

Page 248: DCSLLL

5 Programación

247

y no se borrase el archivo temporal, por lo que antes de crear una nueva, hay que asegurarse que no existe ninguna anterior.

Flujograma Determinar directorio temporal del sistema (Str_CaminoMDB)

Existe el archivo de la base de datos

Si Borrar base de datos anterior (Str_CaminoMDB)

Crear nueva base de datos (Str_CaminoMDB)

Crear tabla etiquetas dirección, campos y determinar clave principal

Crear tabla etiquetas bit, campos y determinar clave principal

Crear tabla etiquetas salto, campos y determinar clave principal

Crear tabla etiquetas subrutina, campos y determinar clave principal

Crear tabla comentarios dirección, campos y determinar clave principal

Crear tabla comentarios bit, campos y determinar clave principal

Crear tabla comentarios línea, campos y determinar clave principal

Crear tabla expresiones de evolución, campos y determinar clave principal

Cerrar base de datos

Fin

5.17.2.3. Public Sub Sub_ConectarBasedeDatos() Abre la nueva base de datos y conecta los objetos Recordset.

Flujograma Conectar nueva base de datos (Dbs_slm)

Conectar tabla etiquetas dirección (Rst_EtiDir y Rst_EtiDir2)

Conectar tabla etiquetas bit (Rst_EtiBit y Rst_EtiBit2)

Conectar tabla etiquetas salto (Rst_EtiSal y Rst_EtiSal)

Conectar tabla etiquetas subrutina (Rst_EtiSub y Rst_EtiSub).

Conectar tabla comentarios dirección (Rst_ComDir y Rst_ComDir2).

Conectar tabla comentarios bit (Rst_ComBit y Rst_ComBit2)

Conectar tabla comentarios línea (Rst_ComLin y Rst_ComLin2)

Conectar tabla exp. evolución (Rst_Evolucion y Rst_Evolucion2)

Fin

5.17.2.4. Public Sub Sub_DesconectarBasedeDatos() Desconecta la base de datos actual

Flujograma Desconectar base de datos (Dbs_slm)

Fin

Page 249: DCSLLL

5 Programación

248

5.17.2.5. Public Sub Sub_BorrarBasedeDatos() Desconecta y Borra la base de datos actual

Flujograma Desconectar base de datos (Dbs_slm)

Borrar base de datos (Str_CaminoMDB)

Fin

5.17.2.6. Public Sub Sub_EscribirRegistroEtiquetaDireccion(Eti_Actual As Etiqueta) Escribe el registro de etiqueta de dirección parametrizado en la tabla correspondiente de

la base de datos.

Siempre que se utilice el programa MS-DOS Loader para editar las etiquetas, es imposible que el archivo de documentación contenga dos etiquetas con el mismo número. Sin embargo, el archivo de documentación puede ser editado usando programas de fabricación propia que por error podrían causar duplicados. Por ello es necesario incluir un control que elimine los duplicados, avisando al usuario de la existencia de etiquetas duplicadas y manteniendo los datos de la última etiqueta encontrada.

Flujograma Existe registro con mismo número

No Añadir nuevo registro

Si Advertir de la duplicidad

Editar registro existente

Fin

IDEM para procedimientos:

• Public Sub Sub_EscribirRegistroEtiquetaBit(Eti_Actual As Etiqueta)

• Public Sub Sub_EscribirRegistroEtiquetaSalto(Eti_Actual As Etiqueta)

• Public Sub Sub_EscribirRegistroEtiquetaSubrutina(Eti_Actual As Etiqueta)

• Public Sub Sub_EscribirRegistroComentarioDireccion(Com_Actual As Comentario)

• Public Sub Sub_EscribirRegistroComentarioBit(Com_Actual As Comentario)

• Public Sub Sub_EscribirRegistroComentarioLinea(Com_Actual As Comentario)

• Public Sub Sub_EscribirRegistroEvolucion(Com_Actual As Comentario)

5.17.2.7. Public Function Fun_LeerRegistroEtiquetaDireccionPorPosicion(Int_Posicion As Integer) As Etiqueta

Lee el registro de etiqueta de dirección de la tabla situado en la posición indicada.

Como siempre va a existir la posición parametrizada, no es necesario un control de error.

Flujograma Ir a primer registro

Avanzar N posiciones

Page 250: DCSLLL

5 Programación

249

Devolver registro

Fin

IDEM para procedimientos:

• Public Function Fun_LeerRegistroEtiquetaBitPorPosicion(…

• Public Function Fun_LeerRegistroEtiquetaSaltoPorPosicion(…

• Public Function Fun_LeerRegistroEtiquetaSubrutinaPorPosicion(…

• Public Function Fun_LeerRegistroComentarioDireccionPorPosicion(…

• Public Function Fun_LeerRegistroComentarioBitPorPosicion(…

• Public Function Fun_LeerRegistroComentarioLineaPorPosicion(…

• Public Function Fun_LeerRegistroEvolucionPorPosicion(…

5.17.2.8. Public Function Fun_LeerRegistroEtiquetaDireccionPorNumero(Int_Numero As Integer) As Etiqueta

Lee el registro de etiqueta de dirección de la tabla con el número indicado.

Si el registro existe, los campos no inicializados son interpretados como cadenas de texto vacías.

Pueden existir direcciones en programa que no tengan etiqueta asociada, por lo que además del control de error es necesario indicarle al módulo de visualización de líneas de programa, que la etiqueta solcitada no existe, para ello, si el registro no existe, devuelve una etiqueta con el campo “Numero” igual a -1 y el resto de campos con cadenas de texto vacías.

Flujograma Buscar registro con el número de etiqueta parametrizado

Existe registro con mismo número

No Devolver etiqueta vacia con campo “NUMERO” igual a -1

Si Devolver registro

Fin

IDEM para procedimientos:

• Public Function Fun_LeerRegistroEtiquetaBitPorNumero(…

• Public Function Fun_LeerRegistroEtiquetaSaltoPorNumero(…

• Public Function Fun_LeerRegistroEtiquetaSubrutinaPorNumero(…

• Public Function Fun_LeerRegistroComentarioDireccionPorNumero(…

• Public Function Fun_LeerRegistroComentarioBitPorNumero(…

• Public Function Fun_LeerRegistroComentarioLineaPorNumero(…

5.17.2.9. Public Function Fun_NRegistrosEtiquetasDireccion() As Integer Devuelve el número de registros existentes en la tabla de etiquetas de dirección.

Page 251: DCSLLL

5 Programación

250

Flujograma Devuelve número de registros

Fin

IDEM para procedimientos:

• Public Function Fun_NRegistrosEtiquetasBit() As Long

• Public Function Fun_NRegistrosEtiquetasSalto() As Integer

• Public Function Fun_NRegistrosEtiquetasSubrutina() As Integer

• Public Function Fun_NRegistrosComentariosDireccion() As Integer

• Public Function Fun_NRegistrosComentariosBit() As Long

• Public Function Fun_NRegistrosComentariosLinea() As Integer

• Public Function Fun_NRegistrosEvolucion() As Integer

5.17.2.10. Public Sub Sub_ExportarMDB(Str_Str_CaminoMDBDestino) Copia la base de datos interna en otro archivo ubicado en la ruta indicada.

Para poder copiar la base de datos sin que se produzca un error, es necesario cerrar los accesos abiertos que tiene el programa sobre la misma.

Flujograma Información al usuario “Exportando base de datos” (Sub_ActualizarBarradeEstado)

Desconectar base de datos temporal (Sub_DesconectarBasedeDatos)

Descargar formulario de documentación (Frm_MDIChildDocumentacion)

Copiar base de datos temporal en la ruta indicada

Conectar base de datos temporal (Sub_ConectarBasedeDatos)

Cargar formulario de documentación (Frm_MDIChildDocumentacion)

Información al usuario “Base de datos exportada” (Sub_ActualizarBarradeEstado)

Fin

5.17.2.11. Public Sub Sub_ImportarMDB(Str_Str_CaminoMDBOrigen) Copia la base de datos ubicada en la ruta recibida en la base de datos temporal.

Para poder copiar la base de datos sin que se produzca un error, es necesario cerrar los accesos que tiene el programa a la misma.

Flujograma Información al usuario “Importando base de datos” (Sub_ActualizarBarradeEstado)

Desconectar base de datos temporal (Sub_DesconectarBasedeDatos)

Descargar formulario de documentación (Frm_MDIChildDocumentacion)

Copiar base de datos de la ruta indicada en la temporal

Conectar base de datos temporal (Sub_ConectarBasedeDatos)

Cargar formulario de documentación (Frm_MDIChildDocumentacion)

Page 252: DCSLLL

5 Programación

251

Información al usuario “Base de datos importada” (Sub_ActualizarBarradeEstado)

Fin

5.17.2.12. Public Sub Sub_DimensionarRstEvolucion() Crea o elimina registros de DBG_Evolucion para que coincidan con el mapeado de

memoria actual.

Así como en el resto de tablas los registros se crean cuando se leen los archivos de documentación correspondientes, en el caso de la tabla de expresiones de evolución esto no es suficiente pues sólo se crearían los registros que hubiesen sido guardados en el archivo *.slm (entorno de simulación) que fueron sólo aquellos que tenían alguna expresión de evolución. De acuerdo al capítulo 5.10.1.2 Evolución de las direcciones, se necesita listar todos los registros que corresponden al mapa de memoria del proyecto actual para poder seleccionar las direcciones de las que realizar el seguimiento.

Este procedimiento es ejecutado cuando se carga el formulario simulación, o cuando se ha producido un cambio en el mapeado de memoria.

Flujograma Eliminar cualquier filtro para acceder a todos los registros

Buscar primer registro zona 1bit (dirección 0)

Existe

No Crear nuevo registro

… Repetir los dos últimos pasos hasta alcanzar el final de la zona de 1 bit

Buscar siguiente registro al final de la zona 1bit

Existe

Si Borrar registro

… Repetir los dos últimos pasos hasta alcanzar principio zona registros (4095)

Buscar primer registro zona registros (dirección 4096)

Existe

No Crear nuevo registró

… Repetir los dos últimos pasos hasta alcanzar el final de la zona de registros

Buscar siguiente registro al final de la zona de registros

Existe

Si Borrar registro

… Repetir los dos últimos pasos hasta alcanzar tamaña máximo (8191)

Fin

5.17.2.13. Public Sub Sub_CambiarFiltroEvolucion() Modifica el recordset, para que filtre sólo los registros que tienen alguna expresión de

evolución.

Page 253: DCSLLL

5 Programación

252

Este procedimiento es ejecutado cuando se guarda el entorno de simulación o cuando se evalúan las expresiones de evolución para realizar la simulación. De esta forma se obtiene una mayor velocidad en el proceso pues sólo se evalúan los registros que contienen datos.

Documentación y decisiones A la hora de implementar este procedimiento aparecieron dos problemas:

• La variable que indica el número de registros del Recordset sólo se actualiza al acceder al último registro del mismo.

• Si se intenta acceder al último registro y no existe ningún registro, se produce un error que aborta el programa.

Es por ello, que primero se realiza una consulta del tipo “SELECT COUNT”que devuelve el número de registros, y sólo en el caso de que exista alguno se accede al último registro.

Flujogramas Aplicar filtro para obtener sólo los registros con expresiones de evolución

Existe algún registro

Si Acceder al último registro

Fin

Page 254: DCSLLL

5 Programación

253

5.18. Módulo de soporte para simular programas (Mdl_Simular) Librería de procedimientos.

Cuando el usuario presiona un botón de la barra de herramientas según la orden de simulación deseada, el formulario Frm_MDI gestiona las llamadas al procedimiento Sub_Simular que controla la ejecución de las líneas de programa de acuerdo a la orden seleccionada.

Este módulo contiene el procedimiento Sub_Simular y los demás procedimientos relacionados.

5.18.1. Documentación y decisiones Todo lo expuesto en el capítulo 5.15 Módulo de soporte interpretar líneas

(Mdl_InterpretarLineas) sobre como evaluar los elementos que componen cada línea para progresar a lo largo de la misma, es aplicable en este capítulo.

5.18.1.1. Decodificación de los elementos Igual que ocurría en el módulo de interpretación de líneas, es necesario identificar los

elementos que forman cada línea y realizar las acciones de progresión y datos encargadas de:

• Acciones de Progresión por la matriz de celdas: Determinan el movimiento sobre la cuadrícula. Por ejemplo, el código “bifurcación descendente en T” provoca bajar a la fila inferior, mientras que el código “contacto normalmente abierto” avanza a la siguiente posición de la misma fila.

• Acciones de escritura de Datos: Determinan que datos evaluar y en que forma. Por ejemplo, el código “contacto normalmente abierto” evalúa el estado lógico de la dirección asociada y sólo propaga un uno si tanto los estados del valor leido como el de la lógica precedente son uno, mientras que el código “constante entera” debe de escribir el valor en la pila si la lógica precedente es uno.

Excepcionalmente el estado lógico se va a propagar por las celdas de interconexión con las acciones de progresión, ya que es en el momento en que se progresa por las celdas cuando resulta más fácil.

Acciones de progresión

Las instrucciones se agrupan de igual forma que en el módulo de interpretación, con la diferencia de que el tipo 10, no existe al ser igual que el tipo 4 pues en este caso no es necesario indicar que el temporizador ocupa tres filas.

• Tipo 1: Operando

• Tipo 2: Operando + bifurcación anterior en T

• Tipo 3: Operando + bifurcación anterior en X

• Tipo 4: Salida

• Tipo 5: Bifurcación descendente en T

• Tipo 6: Bifurcación descendente en X

• Tipo 7: Bifurcación ascendente en T

• Tipo 8: Temporizador retentivo

Page 255: DCSLLL

5 Programación

254

• Tipo 9: Contador

Consultar Tabla 39 y Tabla 40, para ver el grupo que corresponde a cada instrucción.

Acciones de datos En este caso resulta casi imposible agrupar las instrucciones según sus acciones de

progresión.

Por ejemplo, las instrucciones “contacto normalemente abierto” y “contacto normalmente cerrado” que correspondían ambas al tipo 1 de datos, no se comportan de igual forma a la hora de evaluar la lógica. La primera propaga el estado verdadero de la lógica precedente sólo si la dirección asociada contiene un uno, la segunda sólo si es un cero.

Por ello, se ha desarrollado un procedimiento para cada una de las instrucciones.

5.18.1.2. Relación entre el módulo de simulación y el de visualización En el capítulo 5.15.1.2 Relación entre el módulo de simulación y el de visualización, se

determinó que el módulo de simulación debía de inicializar los campos de cada uno de los registros de los elementos que forman la línea, estos campos que permiten la visualización de las líneas de programa con el estado de la simulación.

Los campos son:

• Valor16bits: Valor entero del elemento.

• Valor16bitsPRS: Valor entero del registro Preset si el elemento es un temporizador.

• Valor1bitAntes: Valor lógico del elemento antes de su contribución a la lógica.

• Valor1bitDespues: Valor lógico del elemento después de su contribución a la lógica.

• HaSidoSaltada”): Indica si la línea ha sido ejecutada normalmente o no. El valor será:

- 0 – Línea ejecutada.

- 1 – Línea saltada.

- 2 – Línea no ejecutada.

5.18.1.3. Bases de tiempo de temporizadores

Resumiendo lo expuesto en el capítulo 4.2.3.6 Instrucciones de temporizadores y contadores, se concluye que los temporizadores de 0,01 segundos se comportan de una forma diferente a los de 0,1 y 1 segundo.

Temporizadores de 0,01 segundos Tienen las siguientes características:

• Antes de comenzar la ejecución, se memorizan los registros que implementan acumuladores.

• Los acumuladores se actualizan por una interrupción del sistema cada 0,01 segundos (10 milisegundos).

Para guardar la posición de cada timer se va a crear una tabla dinámica (Tmr_Base001sg) donde cada registro guardará los datos que permitan localizar

Page 256: DCSLLL

5 Programación

255

rápidamente cada temporizador cuando se produce la interrupción. Los campos de cada registro son:

• “Nlinea”: Número de línea en la que aparece el timer.

• “NElemento”: Posición del elemento que codifica el timer dentro de la línea.

• “NDireccionACC”: Contiene la dirección del acumulador del timer evaluado. Como puede existir más de una línea trabajando con el mismo timer para reducir el error, es necesario comprobar que el timer no ha sido ya memorizado para evitar incrementar un acumulador en más de una unidad. Al guardar la dirección del acumulador en los registros anteriores, no es necesario volver a acceder a los elementos para comprobar si ya existe un registro con la misma dirección.

No es conveniente evaluar la actualización de los temporizadores de 0,01 segundos al comienzo de cada ciclo, pues el tiempo de ciclo puede ser superior a 10 milisegundos. La siguiente referencia de tiempo durante la ejecución es el tiempo de línea, que al ser de duración del orden de microsegundos va a ser la utilizada para implementar la interrupción.

Temporizadores de 0,1 y 1 segundo Tienen las siguientes características:

• Cada temporizador se actualiza cuando la línea es evaluada.

• Al comienzo de cada ciclo se determina si los temporizadores de estas dos bases deben de ser actualizados.

Sólo es necesario crear una variable global para cada base (Bool_ActualizarTimers01seg y Bool_ActualizarTimers1seg), que indiquen si se deben incrementar los acumuladores de estos temporizadores, durante el ciclo en curso

5.18.1.4. Evaluación de la evolución de las direcciones En el apartado 5.10 Ventana de simulación (Frm_MDIChildSimulacion) se creó una

tabla en la que el usuario podía introducir unas cadenas de texto que permitían especificar la forma en que debían de evolucionar los valores de cada dirección a lo largo del tiempo, por medio de cadenas formadas por los binomios “Tiempo,Valor” separados con un punto y coma.

La siguiente lista enumera las distintas expresiones de evolución permitidas y el momento en que deben de ser evaluadas por el sistema (LMM o tarjetas de entradas físicas):

• Tabla de estados de entrada de 1 bit (de 0 a un máximo de 2047): Deben de ser evaluadas al comienzo de cada ciclo o por ejecución de la instrucción ISS.

• Tabla de estados de salida de 1 bit (de 0 a un máximo de 8191): Debe de ser evaluada con el ciclo del LMM, siendo éste de ½ “. Así que se van a evaluar al comienzo del ciclo siguiente a que hayan transcurrido ½” desde la última actualización.

• Tabla de estados de entrada de 16 bits correspondientes a tarjetas analógicas (de 0 a un máx. de 2047): Debe de evaluarse la dirección justo en el momento en que se ejecuta la instrucción de lectura (“PULL”).

• Tabla de registros de 16 bits (de 4096 a un máximo de 8191): Debe de ser evaluada con el ciclo del LMM, siendo éste de ½“. Así que se van a evaluar al

Page 257: DCSLLL

5 Programación

256

comienzo del ciclo siguiente a que hayan transcurrido ½” desde la última actualización.

Tablas de evolución de binomios Si en tiempo de ejecución cada vez que se necesitase determinar el valor de una

dirección se tuviese que decodificar la cadena de texto con la expresión de evolución, se haría muy lento el proceso.

Para agilizar el procedimiento, antes de comenzar la ejecución (durante el scan previo) se van a decodificar las cadenas de texto con las expresiones de evolución, escribiendo los binomios “Tiempo,Valor” que corresponden a cada dirección en tres tablas:

• Evo_TablaE1b: Guarda la evolución de la tabla estados de entrada de 1 bit.

• Evo_TablaS1b: Guarda la evolución de la tabla estados de salida de 1 bit.

• Evo_Tabla16b: Guarda la evolución de la tabla estados de entrada de 16 bits y de la tabla de registros de 16 bits.

Cada una de ellas formada por registros con los campos siguientes.

• Numero: Número de la dirección.

• Binomios: Tabla dinámica donde cada registro tiene dos campos: “Tiempo” y “Valor”

• IndiceActual: Guarda el índice del último registro accedido de la tabla “Binomios”, para de esta forma, continuar desde el mismo y no volver a evaluar los binomios que determinan un cambio de estado en un tiempo anterior al actual.

El procedimiento Sub_RellenarBinomiosEvolucionDirecciones es el encargado de realizar esta tarea.

Evaluación de los binomios de evolución La tabla de estados de entrada de 16 bits debe de evaluarse cuando se encuentre una

instrucción PULL. El procedimiento Sub_LeerValorActualEstadoE16b se va encargar de actualizar la dirección de la tabla de memoria de usuario con el valor del binomio correspondiente para el tiempo en curso.

Sin embargo, el resto de tablas o se evalúan al comienzo de cada ciclo (tabla de estados de entrada de 1 bit) o al comienzo del ciclo siguiente a que hayan transcurrido ½” desde la última actualización (Tabla de estados de salida de 1 bit o tabla de registros de 16 bits). El procedimiento Sub_Iss se va a encargar de actualizar las direcciones de las tablas de memoria de usuario con el valor correspondiente para el tiempo en curso.

5.18.2. Procedimientos y funciones públicas

5.18.2.1. Public Sub Sub_EscribirConfiguracionSimulacion(Str_Lineas As String, Lng_Ciclo As Long, Lng_Ejecucion As Long)

Se escriben los parámetros que configuran la simulación con los valores recibidos.

Estos parámetros de simulación son seleccionados por el usuario por medio del formulario Frm_MDIChildSimulacion: líneas a simular, tiempo de ciclo, número de ciclos (tiempo total de simulación).

Flujograma

Escribir parámetros de simulación

Page 258: DCSLLL

5 Programación

257

Fin

5.18.2.2. Public Function Fun_EstadoSimulacion() As EstadoSimulacion_Tipo Devuelve una variable compleja que informa del estado actual de la simulación a otros

procedimientos que lo necesiten.

Los datos devueltos son:

EjecucionIniciada: Indica si se ha iniciado una simulación.

LineasASimular: Cadena de texto con el rango de líneas a simular.

TiempoCiclo: Número de microsegundos que dura la ejecución de un ciclo.

TiempoTotal: Número de microsegundos que se quieren simular.

NCiclos: Número de ciclos que se quieren simular.

TiempoActual: Momento actual de ejecución en microsegundos.

LineaActual: Línea actual en ejecución.

Flujograma Devolver parámetros de simulación

Fin

5.18.2.3. Public Sub Sub_Simular(Enum_Opcion As Integer) Procedimiento público al que accede el formulario Frm_MDI indicando la orden

seleccionada en la barra de herramientas, gestionando las llamadas al resto de procedimientos.

El usuario con los botones de la barra de herramientas puede:

• “Ejecutar una línea”: Ejecuta la siguiente línea del programa. Si la línea en cuestión no corresponde al rango de líneas que se desean simular, automáticamente se salta y se avanza a la siguiente línea hasta encontrar una que sí que corresponda.

• “No ejecutar una línea: Salta la siguiente línea del programa sin ejecutarla. La celda con la información de la línea saltada en la ventana “Programa” muestra el texto “No ejec” para indicar esta situación. Si la línea en cuestión no corresponde al rango de líneas que se desean simular, automáticamente se salta y se avanza a la siguiente línea hasta encontrar una que sí que corresponda.

• “Ejecutar un ciclo”: Se completa un ciclo de programa. Se ejecutan sucesivamente todas las líneas del programa desde la línea actual.

• “Ejecución contínua”: Se ejecuta el programa hasta alcanzar el tiempo de fin de simulación.

• “Reiniciar simulación”: Reinicia (se borran los datos) la simulación actual. Básicamente reinicia el contador de tiempo y se vuelve a la primera línea.

Además de las opciones anteriores es necesario añadir una más, realizada por el formulario Frm_MDI cuando se cierra un proyecto que indica que la simulación ha acabado, así cuando se abra un nuevo proyecto se inicializarán las tablas con los datos de éste y no los del anterior.

Page 259: DCSLLL

5 Programación

258

Documentación y decisiones Las cuatro órdenes primeras consisten en ejecutar una línea o una línea detrás de otra

para completar una línea, un ciclo o el tiempo total de simulación. Así la función básica a realizar es la ejecución de una línea. Será esta rutina la que se encargue de inicializar las variables de programa o ciclo en función del estado de la simulación.

Flujograma Opción seleccionada (Enum_Opcion):

“slmBorrar”

Borrar datos simulación actual (Sub_BorrarSimulacion)

Indicar ejecución no iniciada (Bool_EjecucionInicializada)

“slm_Reiniciar”

Reiniciar ejecución (Sub_ReiniciarSimulacion)

Indicar ejecución no iniciada (Bool_EjecucionInicializada)

“slm_SimularContinua”

Se ha alcanzado tiempo total de simulación?

No Ejecutar siguiente línea (Sub_ComenzarLinea)

… Repetir los dos últimos pasos

Indicar fin de ejecución

“slm_SimularCiclo”

Fin de ciclo?

No Se ha alcanzado tiempo total de simulación?

Si Indicar fin de ejecución

No Ejecutar siguiente línea (Sub_ComenzarLinea)

… Repetir los cuatro últimos pasos

“slm_SimularLinea”

Se ha alcanzado tiempo total de simulación?

Si Indicar fin de ejecución

No Saltar siguiente línea (Sub_ComenzarLinea)

La línea estaba incluida en el rango de líneas a ejecutar?

No … Repetir los cuatro últimos pasos

“slm_NoEjecutarLinea”

Se ha alcanzado tiempo total de simulación?

Si Indicar fin de ejecución

No Ejecutar siguiente línea (Sub_ComenzarLinea)

La línea estaba incluida en el rango de líneas a ejecutar?

No … Repetir los cuatro últimos pasos

Page 260: DCSLLL

5 Programación

259

Fin

5.18.2.4. Procedimientos y funciones de gestión de la simulación

5.18.2.5. Private Sub Sub_BorrarSimulacion() Hay que tener en cuenta que al abrir y cerrar el proyecto se cargan y descargan los

formularios, por lo que se inicializan todas sus variables automáticamente. Esto no ocurre con los módulos, que necesitan una función que lo realice.

Esta rutina se encarga de borrar las tablas del módulo para liberar memoria e inicializar los parámetros de simulación.

El resto de variables de datos y progreso ya serán inicializadas cuando se comience la simulación del nuevo proyecto.

Flujograma Parámetros de simulación (líneas, tiempo ciclo y tiempo total) a valores por defecto

Borrar tablas

Fin

5.18.2.6. Private Sub Sub_ReiniciarSimulacion() Reinicia la simulación actual teniendo en cuenta si se han producido cambios en los

datos de la ventana de simulación. Para ello es necesario:

• Variables de progreso de programa a cero

• Reconstruir tablas de evolución de direcciones entradas.

• Reconstruir tablas de seguimiento de direcciones.

El número de línea actual en vez de cero se inicializa al número total de líneas de programa, para que la rutina de comienzo de línea llame a la de comienzo de ciclo.

Flujograma Inicializar número de líneas totales (Lng_NLineasTotal)

Inicializar tiempo de simulación de una línea (Dbl_TiempoLinea)

Número de línea actual = Lng_NLineasTotal (Lng_NLineaActual)

Tiempo actual = 0 (Dbl_TiempoActual)

Bases de tiempo temporizadores = 0

Inicializar pila (Sub_InicializarPilayOperaciones)

Borrar campos de contenido de memoria de usuario (Sub_BorrarMemoriadeUsuario)

Borrar campos de estado de todas las líneas (Sub_InicializarEstadosLineas)

Rellenar tablas de timers, contadores y saltos (Sub_RellenarTablasSimulacion)

Rellenar tabla evolución direcciones de entrada (Sub_RellenarBinomiosEvolucionDirecciones)

Marcar direcciones con seguimiento de evolución (Sub_MarcarDireccionesConSeguimientoEvolucion)

Recontruir tabla direcciones con seguimiento de evolución (Sub_CrearTablaEvolucionSalidas)

Page 261: DCSLLL

5 Programación

260

Fin

5.18.2.7. Private Sub Sub_ComenzarCiclo() Este procedimiento gestiona las variables de alcance ciclo.

Flujograma Evaluar cambios en las direcciones de entrada de 1bit (Sub_ISS)

Actualizar bases de tiempo 0,1 y 1 seg, (Sub_DeterminarActualizarTimers01y1)

Se desactiva el salto que pudiera estar activado (Act_SaltoActivo)

Fin

5.18.2.8. Private Sub Sub_ComenzarLinea(Optional Bool_NoEjecutar As Boolean) Este procedimiento gestiona las variables de alcance línea.

Tal y como se ha expuesto anteriormente, esta rutina gestiona la evolución de todo el proceso de simulación, realizando las llamadas al resto de procedimientos en función de si se deben de actualizar las variables de datos y de progreso de programa, de datos y de progreso de ciclo o simplemente las de datos y de progreso de línea.

Flujograma Se ha iniciado la simulación?

No Inicializar simulación (Sub_ReiniciarSimulacion)

Indicar simulación en curso (Bool_SimulacionInicializada)

Final de ciclo?

Si Volver a la primera línea del programa (Lng_NLineaActual)

Inicializar ciclo (Sub_ComenzarCiclo)

No Incrementar número de línea (Lng_NLineaActual)

Actualizar timers base de tiempo 0,01 seg, (Sub_DeterminarActualizarTimers001)

Borrar campos de estado de la línea (Sub_InicializarEstadoLinea)

Leer regitro de la línea actual (Fun_LeerRegistroLineaPrograma)

Línea no en rango o el usuario no quiere ejecutar la línea (Bool_NoEjecutar)?

Si Indicar línea no ejecutada (HaSidoSaltada=2)

Hay un salto activo (Act_SaltoActual)?

Si Indicar línea saltada (HaSidoSaltada=1)

No Simular línea (Sub_SimularLinea)

Escribir regitro de la línea actual (Suyb_EscribirRegistroLineaPrograma)

Incrementar tiempo actual (Dbl_TiempoActual)

Actualizar barra de progreso (Sub_ActualizarBarradeProgreso)

Fin

Page 262: DCSLLL

5 Programación

261

5.18.2.9. Private Sub Sub_SimularLinea() Se ejecuta la línea. Se rellenan variables de datos de línea y se inicializan variables de

progreso de línea.

Flujograma Inicializar matriz de información (Inf_Celdas)

Hay un salto activo (Act_SaltoActual)?

No Inicializa celdas 1,0 a 1,4 con estado logico “1”

Si Inicializa celdas 1,0 a 1,4 con estado logico “0”

Inicializa variables de control de progreso a celda 2,0

Determina si existe un timer retentivo en la línea (Fun_ExisteTimerRetentivo)

Determina si existe un contador en la línea (Fun_ExisteContador)

Leer siguiente elemento (Ele_Actual)

Simular elemento (Sub_SimularElemento)

Escribir elemento (Ele_Actual)

… Repetir los dos últimos pasos hasta interpretar el último elemento.

5.18.2.10. Private Sub Sub_SimularElemento() Identifica el elemento recibido en función del opcode y de acuerdo a la clasificación de

las tablas Tabla 39 (el grupo 10 corresponde al grupo 4) y Tabla 40 llama al procedimiento que le corresponde de acciones de progreso y al procedimiento de acciones de datos desarrollado para cada elemento.

Flujograma Identificar opcode del elemento actual (Ele_actual)

Contacto normalmente abierto (hC8)

Acciones de progresión (Sub_Tipo1VariablesdeProgreso)

Acciones de datos (Sub_TratamientoCodigohC8oC9oCA)

… Repetir para todos los opcodes.

Fin

5.18.3. Procedimientos y funciones de acciones de progreso Agrupa los procedimientos:

• Private Sub Sub_Tipo1VariablesdeProgreso()

• Private Sub Sub_Tipo2VariablesdeProgreso()

• Private Sub Sub_Tipo3VariablesdeProgreso()

• Private Sub Sub_Tipo4VariablesdeProgreso()

• Private Sub Sub_Tipo5VariablesdeProgreso()

• Private Sub Sub_Tipo6VariablesdeProgreso()

• Private Sub Sub_Tipo7VariablesdeProgreso()

Page 263: DCSLLL

5 Programación

262

• Private Sub Sub_Tipo8VariablesdeProgreso()

• Private Sub Sub_Tipo9VariablesdeProgreso()

El código de estos procedimientos es el mismo que el de los procedimientos con el mismo nombre del capítulo 5.15 Módulo de soporte interpretar líneas (Mdl_InterpretarLineas) con la diferencia de que en este caso no es necesario rellenar las celdas de interconexión saltadas (cuando se estaban interpretando las líneas sí que era necesario, para definir las líneas de interconexión entre celdas con elementos).

5.18.4. Procedimientos y funciones de acciones de datos

5.18.4.1. Private Sub Sub_TratamientoCodigohC8oC9oCA() El código hC8 corresponde al opcode de contacto normalmente abierto, el código hC9

al de contacto normalmente abierto con bifurcación anterior en T y el código hCA al de contacto normalmente abierto con bifurcación anterior en X.

La diferencia entre los tres está en como modifican las variables de progreso, es por ello que comparten la misma rutina de variables de datos.

El flujograma implementa el funcionamiento descrito para estos elementos en el capítulo 4 Interpretación MS-DOS Loader.

Si el valor del registro de memoria indicado y el valor de la lógica precedente son 1, pasa un 1. Si cualquiera es 0 pasa un 0.

Flujograma Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

El elemento está forzado?

Si Leer valor a forzar (bit histórico)

No Obtener número de dirección (Fun_MSBLSBaEntero)

Leer valor 1 bit contenido en la dirección (Fun_LeerRegistroMemUContenido1b)

Determinar resultado = lógica precedente & valor seleccionado

Actualizar matriz de información (Sub_CeldaSiguienteValor1b)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.2. Private Sub Sub_TratamientoCodigohCCoCDoCE() Es el mismo caso que la rutina anterior pero en vez de contacto normalmente abierto es

un contacto normalmente cerrado.

El flujograma implementa el funcionamiento descrito para estos elementos en el capítulo 4 Interpretación MS-DOS Loader.

Si el valor del registro de memoria indicado es 0 y el valor de la lógica precedente es 1, pasa un 1. En cualquier otro caso pasa un 0.

Flujograma Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

El elemento está forzado?

Page 264: DCSLLL

5 Programación

263

Si Leer valor a forzar (bit histórico)

No Obtener número de dirección (Fun_MSBLSBaEntero)

Leer y negar el valor 1 bit contenido en la dirección (Fun_LeerRegistroMemUContenido1b)

Determinar resultado = lógica precedente & valor seleccionado

Actualizar matriz de información (Sub_CeldaSiguienteValor1b)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.3. Private Sub Sub_TratamientoCodigoh43() El código h43 corresponde al opcode de contacto transicional a ON.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Si el valor del registro de memoria indicado tiene un flanco ascendente (el valor actual es 1 y en el ciclo anterior era 0 (bit histórico)) y el valor de la lógica precedente es 1, pasa un 1. En cualquier otro caso pasa un 0.

Flujograma Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

El elemento está forzado?

Si Leer valor a forzar (bit histórico)

No Obtener número de dirección (Fun_MSBLSBaEntero)

Leer el valor 1 bit contenido en la dirección y detectar flanco ascendente (Fun_LeerRegistroMemUContenido1b)

Actualizar bit histórico

Determinar resultado = lógica precedente & valor seleccionado

Actualizar matriz de información (Sub_CeldaSiguienteValor1b)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

IDEM para procedimientos:

• Public Sub Sub_TratamientoCodigoh4B(): Contacto transicional a OFF.

5.18.4.4. Private Sub Sub_TratamientoCodigohC4oC5() El código hC4 corresponde al opcode de salida no retentiva y el hC5 al de salida

retentiva.

El flujograma implementa el funcionamiento descrito para estos elementos en el capítulo 4 Interpretación MS-DOS Loader.

Escribe el valor de la lógica precedente en el registro de memoria indicado.

Flujograma Obtener número de dirección (Fun_MSBLSBaEntero)

Page 265: DCSLLL

5 Programación

264

Existe un salto activo?

Si El elemento no está forzado y primer ciclo salto NSKD?

Si Escribir 0 en dir. (Sub_EscribirRegistroMemUContenido1bS)

No El elemento está forzado?

Si Resultado = Leer valor a forzar (bit histórico)

No Resultado = Valor lógica precedente teniendo en cuenta overflow de operaciones matemáticas (Fun_CeldaAnteriorValor1b)

Escribir resultado en la dir. (Sub_EscribirRegistroMemUContenido1bS)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.5. Private Sub Sub_TratamientoCodigohC6() El código hC6 corresponde al opcode de salida latch.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Si el valor de la lógica precedente es 1, escribe 1 en el registro de memoria indicado. Si es 0, lo mantiene igual.

Flujograma Obtener número de dirección (Fun_MSBLSBaEntero)

Existe un salto activo?

Si Resultado = 0

No El elemento está forzado?

Si Resultado = bit histórico con el valor a forzar (Ele_Actual)

No Resultado = Valor lógica precedente teniendo en cuenta overflow de operaciones matemáticas (Fun_CeldaAnteriorValor1b)

Resultado = 1?

Si Escribir 1 en la dirección (Sub_EscribirRegistroMemUContenido1bS)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

IDEM para procedimientos:

• Public Sub Sub_TratamientoCodigohC7(): Salida unlatch.

5.18.4.6. Private Sub Sub_TratamientoCodigohC1() El código hC1 corresponde al opcode de bifurcación descendente en T.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Page 266: DCSLLL

5 Programación

265

Flujograma Se ha producido un cambio de fila?

Si Copiar valor lógica precedente desde la fila superior (Sub_CeldaAnteriorValor1bCopiardeArriba)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.7. Private Sub Sub_TratamientoCodigohC2() El código hC2 corresponde al opcode de bifurcación descendente en X.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Copiar valor lógica precedente desde la fila superior

(Sub_CeldaAnteriorValor1bCopiardeArriba)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.8. Private Sub Sub_TratamientoCodigohC3() El código hC3 corresponde al opcode de bifurcación ascendente en T o en X.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Resultado = valor lógica precedente fila inferior (Fun_CeldaAnteriorValor1b) OR

valor lógica precedente fila superior (Fun_CeldaSiguienteValor1b)

Escribir resultado en celda fila superior (Sub_CeldaSiguienteValor1b)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.9. Private Sub Sub_TratamientoCodigoh4Ao49() El código h4A corresponde al opcode de temporizador con retardo a ON de base 1

segundo y el h49 al temporizador con retardo a ON de base 0,1 segundos.

El flujograma implementa el funcionamiento descrito para estos elementos en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección del registro acumulador (Fun_MSBLSBaEntero)

Obtener valor 16 bits registro acumulador (Fun_LeerRegistroMemUContenido16b)

Obtener número de dirección del registro preset (Fun_MSBLSBaEntero)

Obtener valor 16 bits registro preset (Fun_LeerRegistroMemUContenido16b)

Existe un salto activo?

Si Primer ciclo salto NSKD?

Page 267: DCSLLL

5 Programación

266

Si Escribir reg. ACC = 0 (Sub_EscribirRegistroMemUContenido16b)

No Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 1?

Si Es el primer ciclo en el que se activa el temporizador?

No Base de tiempos del temporizador?

1 segundo Hay que actualizar el ACC del temporizador?

Si Incrementar y escribir el valor del registro ACC (Sub_EscribirRegistroMemUContenido16b)

0,1 segundo Hay que actualizar el ACC del temporizador?

Si Incrementar y escribir el valor del registro ACC (Sub_EscribirRegistroMemUContenido16b)

Actualizar bit histórico = 1

Final de temporización?

Si Salida = 1

No Salida = 0

No Salida = 0

Actualizar bit histórico = 0

Escribir reg. ACC = 0 (Sub_EscribirRegistroMemUContenido16b)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.10. Private Sub Sub_TratamientoCodigoh68() El código h68 corresponde al opcode de temporizador con retardo a ON de base 0,01

segundos.

El flujograma implementa el funcionamiento descrito para estE elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección del registro acumulador (Fun_MSBLSBaEntero)

Obtener valor 16 bits registro acumulador (Fun_LeerRegistroMemUContenido16b)

Obtener número de dirección del registro preset (Fun_MSBLSBaEntero)

Obtener valor 16 bits registro preset (Fun_LeerRegistroMemUContenido16b)

Existe un salto activo?

Si Indicar que no hay que actualizar el temporizador (bit histórico)

Primer ciclo salto NSKD?

Si Escribir reg. ACC = 0 (Sub_EscribirRegistroMemUContenido16b)

No Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Page 268: DCSLLL

5 Programación

267

Lógica precedente = 1?

Si Indicar que hay que actualizar el temporizador (bit histórico)

Final de temporización?

Si Salida = 1

No Salida = 0

No Salida = 0

Indicar que no hay que actualizar el temporizador (bit histórico)

Escribir reg. ACC = 0 (Sub_EscribirRegistroMemUContenido16b)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.11. Private Sub Sub_TratamientoCodigoh42o41() El código h42 corresponde al opcode de temporizador con retardo a OFF de base 1

segundo y el h41 al temporizador con retardo a OFF de base 0,1 segundos.

El flujograma implementa el funcionamiento descrito para estos elementos en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección del registro acumulador (Fun_MSBLSBaEntero)

Obtener valor 16 bits registro acumulador (Fun_LeerRegistroMemUContenido16b)

Obtener número de dirección del registro preset (Fun_MSBLSBaEntero)

Obtener valor 16 bits registro preset (Fun_LeerRegistroMemUContenido16b)

Existe un salto activo?

Si Primer ciclo salto NSKD?

Si Escribir reg. ACC = 0 (Sub_EscribirRegistroMemUContenido16b)

No Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 0?

Si Es el primer ciclo en el que se activa el temporizador?

Si Base de tiempos del temporizador?

1 segundo Hay que actualizar el ACC del temporizador?

Si Incrementar y escribir el valor del registro ACC (Sub_EscribirRegistroMemUContenido16b)

0,1 segundo Hay que actualizar el ACC del temporizador?

Si Incrementar y escribir el valor del registro ACC (Sub_EscribirRegistroMemUContenido16b)

Actualizar bit histórico = 0

Final de temporización?

Page 269: DCSLLL

5 Programación

268

Si Salida = 0

No Salida = 1

No Salida = 1

Actualizar bit histórico = 1

Escribir reg. ACC = 0 (Sub_EscribirRegistroMemUContenido16b)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.12. Private Sub Sub_TratamientoCodigoh60() El código h60 corresponde al opcode de temporizador con retardo a OFF de base 0,01

segundos.

El flujograma implementa el funcionamiento descrito para estE elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección del registro acumulador (Fun_MSBLSBaEntero)

Obtener valor 16 bits registro acumulador (Fun_LeerRegistroMemUContenido16b)

Obtener número de dirección del registro preset (Fun_MSBLSBaEntero)

Obtener valor 16 bits registro preset (Fun_LeerRegistroMemUContenido16b)

Existe un salto activo?

Si Indicar que no hay que actualizar el temporizador (bit histórico)

Primer ciclo salto NSKD?

Si Escribir reg. ACC = 0 (Sub_EscribirRegistroMemUContenido16b)

No Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 0?

Si Indicar que hay que actualizar el temporizador (bit histórico)

Final de temporización?

Si Salida = 0

No Salida = 1

No Salida = 1

Indicar que no hay que actualizar el temporizador (bit histórico)

Escribir reg. ACC = 0 (Sub_EscribirRegistroMemUContenido16b)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

Page 270: DCSLLL

5 Programación

269

5.18.4.13. Private Sub Sub_TratamientoCodigoh4Eo4D() El código h4E corresponde al opcode de temporizador con retentivo de base 1 segundo

y el h4D al temporizador retentivo de base 0,1 segundos.

El flujograma implementa el funcionamiento descrito para estos elementos en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección del registro acumulador (Fun_MSBLSBaEntero)

Obtener valor 16 bits registro acumulador (Fun_LeerRegistroMemUContenido16b)

Obtener número de dirección del registro preset (Fun_MSBLSBaEntero)

Obtener valor 16 bits registro preset (Fun_LeerRegistroMemUContenido16b)

Existe un salto activo?

No Entrada RESET activada (Fun_CeldaAnteriorValor1b)

Si Salida = 0

Escribir reg. ACC = 0 (Sub_EscribirRegistroMemUContenido16b)

No Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 1?

Si Es el primer ciclo en el que se activa el temporizador?

Si Base de tiempos del temporizador?

1 segundo Hay que actualizar el ACC del timer?

Si Incrementar y escribir el valor del registro ACC (Sub_EscribirRegistroMemUContenido16b)

0,11 segundo Hay que actualizar el ACC del timer?

Si Incrementar y escribir el valor del registro ACC (Sub_EscribirRegistroMemUContenido16b)

Final de temporización?

Si Salida = 1

No Salida = 0

Actualizar bit histórico

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.14. Private Sub Sub_TratamientoCodigoh4F() El código h4F corresponde al opcode de contador.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección del registro acumulador (Fun_MSBLSBaEntero)

Page 271: DCSLLL

5 Programación

270

Obtener valor 16 bits registro acumulador (Fun_LeerRegistroMemUContenido16b)

Obtener número de dirección del registro preset (Fun_MSBLSBaEntero)

Obtener valor 16 bits registro preset (Fun_LeerRegistroMemUContenido16b)

Existe un salto activo?

No Entrada RESET activada (Fun_CeldaAnteriorValor1b)

Si Salida = 0

Escribir reg. ACC = 0 (Sub_EscribirRegistroMemUContenido16b)

No Flanco ascendente en entrada CTU (Fun_CeldaAnteriorValor1b)

Si Incrementar y escribir el valor del registro ACC (Sub_EscribirRegistroMemUContenido16b)

Flanco ascendente en entrada CTD (Fun_CeldaAnteriorValor1b)

Si Decrementar y escribir el valor del registro ACC (Sub_EscribirRegistroMemUContenido16b)

Registro acumulador = registro preset?

Si Salida = 1

No Salida = 0

Actualizar bits históricos

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.15. Private Sub Sub_TratamientoCodigoh46() El código h46 corresponde al opcode de no salto con retención.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Existe un salto activo?

No El elemento está forzado?

Si Leer bit histórico con el valor a forzar (Ele_Actual)

No Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

El valor seleccionado es 0?

Si Obtener número de salto (Fun_MSBLSBaEntero)

Determinar tipo de salto según el número

Salto 0-8191, 8449-32767 Se activa el salto NSKR

Salto directo 8192-8447

Leer línea de destino del salto (Fun_NLineaDestinoSaltoNSKR)

Saltar a la línea de destino (Sub_SaltarLineas)

Page 272: DCSLLL

5 Programación

271

Salto indirecto 8448

Leer de la pila el nuevo número de salto (Fun_LeerDatodePila)

Determinar tipo de salto según el número

Salto 0-8191, 8449-32767 Se activa el salto NSKR

Salto directo 8192-8447

Leer línea de destino del salto (Fun_NLineaDestinoSaltoNSKR)

Saltar a la línea de destino (Sub_SaltarLineas)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.16. Private Sub Sub_TratamientoCodigoh47() El código h47 corresponde al opcode de no salto con desactivación.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Existe un salto activo?

No El elemento está forzado?

Si Leer bit histórico con el valor a forzar (Ele_Actual)

No Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

El valor seleccionado es 0?

Si Obtener número de salto (Fun_MSBLSBaEntero)

Primer ciclo en el que se activa el salto?

Si Se activa el salto NSKD

No Se activa el salto NSKR

Actualizar bit histórico

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.17. Private Sub Sub_TratamientoCodigoh34() El código h34 corresponde al opcode de fin de salto.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Obtener número de salto (Fun_MSBLSBaEntero)

Page 273: DCSLLL

5 Programación

272

Existe un salto activo por subrutina?

No Existe un salto activo por NSK?

Si El salto activo coincide con el número del fin de salto?

Si Desactivar el salto

No El número de salto es el de un salto directo (8192-8447)?

Si Guardar estado del fin de salto (Sub_EscribirEstadoDestinoSaltoNSKR)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.18. Private Sub Sub_TratamientoCodigoh88() El código h88 corresponde al opcode de lectura de datos “bring in”.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección a partir del parámetro (Fun_MSBLSBaEntero)

Leer valor 16 bits contenido en la dir (Fun_LeerContenido16de1o16LSBConSigno)

Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 1?

Si Escribir el valor de 16 bits en la pila (Sub_EscribirDatoenPila)

Existe una operación pendiente?

Si Realizar operación (Fun_RealizarOperacion)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.19. Private Sub Sub_TratamientoCodigoh89() El código h89 corresponde al opcode de lectura de datos indirecta.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección de referencia (Fun_MSBLSBaEntero)

Leer valor 16 bits (dir. efectiva) (Fun_LeerContenido16de1o16LSBConSigno)

Leer valor 16 bits contenido en la dir (Fun_LeerContenido16de1o16LSBConSigno)

Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 1?

Si Escribir el valor de 16 bits en la pila (Sub_EscribirDatoenPila)

Page 274: DCSLLL

5 Programación

273

Existe una operación pendiente?

Si Realizar operación (Fun_RealizarOperacion)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.20. aPrivate Sub Sub_TratamientoCodigoh7() El código h7 corresponde al opcode de escritura de datos.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección (Fun_MSBLSBaEntero)

Leer valor 16 bits contenido en la dir (Fun_LeerContenido16de1o16LSBConSigno)

Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Existe un salto activo?

Si El elemento no está forzado y primer ciclo salto NSKD?

Si Escribir 0 en dir. (Sub_EscribirContenido16en1o16LSBConSigno)

No El elemento está forzado?

No Lógica precedente = 1 o se ha realizado una operación matemática?

Si Obtener dato de la pila (Fun_LeerDatodePila)

Escribir dato en la dirección (Sub_EscribirContenido16en1o16LSBConSigno)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.21. Private Sub Sub_TratamientoCodigoh6() El código h6 corresponde al opcode de escritura de datos indirecta.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección de referencia (Fun_MSBLSBaEntero)

Obtener número de dir efectiva (Fun_LeerContenido16de1o16LSBConSigno)

Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Existe un salto activo?

Si Primer ciclo salto NSKD?

Si Escribir 0 en la dir (Sub_EscribirContenido16en1o16LSBConSigno)

No Lógica precedente = 1 o se ha realizado una operación matemática?

Page 275: DCSLLL

5 Programación

274

Si Obtener dato de la pila (Fun_LeerDatodePila)

Escribir dato en la dir (Sub_EscribirContenido16en1o16LSBConSigno)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.22. Private Sub Sub_TratamientoCodigoh8B() El código h8B corresponde al opcode de constante.

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 1?

Si Obtener valor 16 bits a partir del parámetro (Fun_MSBLSBaEntero)

Escribir el valor de 16 bits en la pila (Sub_EscribirDatoenPila)

Existe una operación pendiente?

Si Realizar operación (Fun_RealizarOperacion)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.23. Private Sub Sub_TratamientoCodigoh80() El código h80 corresponde al opcode de lectura de datos 1-8 bloques de 16 bits zona I/O

(PULL).

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección y número de bloques (Fun_MSBLSBaEntero)

Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 1?

Si Determinar rango de dirección

0-2047 Evaluar evolución de la dirección de entrada de 16 bits (Sub_LeerValorActualEstadoE16b)

Leer valor 16 bits contenido en la dir (Fun_LeerContenido16de1o16LSBConSigno)

2048-4095 Obtener valor de 16 bits a partir de dos valores de 8 bits (Fun_LeerRegistroMemSContenido8b)

Escribir el valor de 16 bits en la pila (Sub_EscribirDatoenPila)

… Repetir los cuatro últimos pasos hasta evaluar todos los bloques

Page 276: DCSLLL

5 Programación

275

Existe una operación pendiente?

Si Realizar operación (Fun_RealizarOperacion)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.24. Private Sub Sub_TratamientoCodigoh82() El código h82 corresponde al opcode de lectura de datos 1-8 bloques de 16 bits zona

Registros (PULL).

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección y número de bloques (Fun_MSBLSBaEntero)

Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 1?

Si Leer valor 16 bits de la dir (Fun_LeerContenido16de1o16LSBConSigno)

Escribir el valor de 16 bits en la pila (Sub_EscribirDatoenPila)

… Repetir los tres últimos pasos hasta evaluar todos los bloques

Existe una operación pendiente?

Si Realizar operación (Fun_RealizarOperacion)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.25. Private Sub Sub_TratamientoCodigoh84() El código h84 corresponde al opcode de escritura de datos 1-8 bloques de 16 bits zona

I/O (PUSH).

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección y número de bloques (Fun_MSBLSBaEntero)

Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Existe un salto activo y no es primer ciclo salto NSKD?

No Primer ciclo salto NSKD?

Si Escribir 0 en la dir (Sub_EscribirContenido16en1o16LSBConSigno)

No Lógica precedente = 1 o se ha realizado una operación matemática?

Si Obtener dato de la pila (Fun_LeerDatodePila)

Escribir dato en la dirección (Sub_EscribirContenido16en1o16LSBConSigno)

Page 277: DCSLLL

5 Programación

276

… Repetir los cinco últimos pasos hasta evaluar todos los bloques

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.26. Private Sub Sub_TratamientoCodigoh86() El código h86 corresponde al opcode de escritura de datos 1-8 bloques de 16 bits zona

Registros (PUSH).

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de dirección y número de bloques (Fun_MSBLSBaEntero)

Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Existe un salto activo y no es primer ciclo salto NSKD?

No Primer ciclo salto NSKD?

Si Escribir 0 en la dir (Sub_EscribirContenido16en1o16LSBConSigno)

No Lógica precedente = 1 o se ha realizado una operación matemática?

Si Obtener dato de la pila (Fun_LeerDatodePila)

Escribir dato en la dirección (Sub_EscribirContenido16en1o16LSBConSigno)

… Repetir los cinco últimos pasos hasta evaluar todos los bloques

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.27. Private Sub Sub_TratamientoCodigoh8o9oA()

El código h8 corresponde al opcode de igual que, el código h9 al de menor que y el código hA al de mayor que.

El flujograma implementa el funcionamiento descrito para estos elementos en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 1?

Si Indicar que existe una operación pendiente

Determinar tipo de operación?

Igual que Indicar que la operación pendiente es “igual que”

Mayor que Indicar que la operación pendiente es “mayor que”

Menor que Indicar que la operación pendiente es “menor que”

Actualizar matriz de información (Inf_Celdas)

Page 278: DCSLLL

5 Programación

277

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.28. Private Sub Sub_TratamientoCodigoh8D() El código h8D corresponde al opcode de prueba de cero.

El flujograma implementa el funcionamiento descrito para estos elementos en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 1?

Si Obtener dato de la pila (Fun_LeerDatodePila)

El dato recuperado es cero?

Si Pasa un 1

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.29. Private Sub Sub_TratamientoCodigohEoDoCoB() El código hE corresponde al opcode de suma, el código hD al de resta, el código hC al

de multiplicación y el código hB al de división.

El flujograma implementa el funcionamiento descrito para estos elementos en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Lógica precedente = 1?

Si Indicar que existe una operación pendiente

Indicar que se ha realizado una operación matemática en la línea

Determinar tipo de operación?

Suma Indicar que la operación pendiente es “suma”

Resta Indicar que la operación pendiente es “resta”

Multiplicación Indicar que la operación pendiente es “multiplicación”

División Indicar que la operación pendiente es “división”

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.30. Private Sub Sub_TratamientoCodigoh4() El código h4 corresponde al opcode de salto a subrutina (JSR).

Page 279: DCSLLL

5 Programación

278

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de subrutina (Fun_LSBaEntero)

Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Leer siguiente elemento de la línea cuyo parámetro contiene la línea de destino

Existe un salto activo?

No Valor lógica precedente = 1?

Si Guardar número de línea de retorno (Org_Subrutinas)

Indicar subrutina ejecutada por JSR (Org_Subrutinas)

Obtener número de línea de destino (Fun_MSBLSBaEntero)

Saltar a la línea de destino

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.31. Private Sub Sub_TratamientoCodigoh24() El código h24 corresponde al opcode de subrutina (SUB).

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de subrutina (Fun_LSBaEntero)

Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Existe un salto activo?

No Valor lógica precedente = 0?

Si Activar salto por subrutina hasta instrucción RTS (Act_SaltoActual)

No Indicar subrutina ejecutada no por JSR (Org_Subrutinas)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.32. Private Sub Sub_TratamientoCodigoh14() El código h14 corresponde al opcode de retorno a subrutina (RTS).

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Obtener número de subrutina (Fun_LSBaEntero)

Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Page 280: DCSLLL

5 Programación

279

Existe un salto activo por NSK?

No Existe un salto activo por SUB y coincide el número de salto?

Si Desactivar salto activo (Act_SaltoActual)

No La subrutina fue ejecutada por un JSR (Org_Subrutinas)?

Desactivar subrutina ejecutada por un JSR (Org_Subrutinas)

Si Valor lógica precedente = 1?

Retornar a la línea de siguiente a la inst. JSR (Org_Subrutinas)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.33. Private Sub Sub_TratamientoCodigoh5() El código h5 corresponde al opcode de retorno a principio de programa (RBP).

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Existe un salto activo?

No El elemento está forzado?

Si Resultado = bit histórico con el valor a forzar (Ele_Actual)

No Resultado = valor lógica precedente (Ele_Actual)

Resultado = 1?

Si Saltar al comienzo del programa

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.4.34. Private Sub Sub_TratamientoCodigoh8F() El código h8F corresponde al opcode de exploración de estado de entradas (ISS).

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Existe un salto activo?

No Explorar estado de las entradas (Sub_ISS)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

Page 281: DCSLLL

5 Programación

280

5.18.4.35. Private Sub Sub_TratamientoCodigohFFo00() Tanto el código hFF como el h00 corresponden al opcode de no operando (NOP).

El flujograma implementa el funcionamiento descrito para este elemento en el capítulo 4 Interpretación MS-DOS Loader.

Flujograma Leer valor lógica precedente (Fun_CeldaAnteriorValor1b)

Actualizar matriz de información (Inf_Celdas)

Actualizar campos para la visualización gráfica (Ele_Actual)

Fin

5.18.5. Procedimientos y funciones auxiliares

5.18.5.1. Private Function Fun_LineaActualEnRango() As Boolean Se comprueba si la línea actual pertenece al rango de líneas seleccionado por el usuario

en la ventana simulación para ser simuladas.

Documentación y decisiones La forma en que el usuario debe de indicar las líneas es la siguiente:

• Selección de líneas sueltas: “1,2,6” implica ejecutar líneas 1, 2 y 6.

• Selección de rangos de líneas: “1-3” implica ejecutar líneas 1, 2 y 3.

• Combinación de ambos estilos: “1,4-6,9” implica ejecutar líneas 1, 4, 5, 6 y 9.

• La celda en blanco equivale a simular todas las líneas.

No es necesario realizar un tratamiento de error de sintaxis, pues ya lo realiza el formulario simulación cuando el usuario cambia el valor del parámetro.

Flujograma Existe cadena de texto?

No Indicar que el número de línea solicitado está en el rango

Fin

Extraer primer número que será tratado como límite inferior

Extraer siguiente caracter que será tratado como caracter de separación?

“,” o fin Número línea solicitado = Límite inferior?

Si Indicar que el número de línea solicitado está en el rango

Fin

No … Repetir los cinco últimos pasos hasta final de cadena de texto

“-” Extraer siguiente número que será tratado como límite superior

Extraer siguiente caracter que será tratado como caracter de separación?

Número línea solicitado dentro del rango límite inferior-superior?

Si Indicar que el número de línea solicitado está en el rango

Fin

Page 282: DCSLLL

5 Programación

281

No … Repetir los once últimos pasos hasta final de cadena de texto

Fin

5.18.5.2. Private Sub Sub_RellenarTablasSimulacion() Este procedimiento es ejecutado cuando se inicia una nueva simulación.

Realiza, entre otras, las acciones equivalentes al scan retentivo del Logic Manager antes de empezar la ejecución cíclica de un programa.

Documentación y decisiones

Temporizador con retardo a ON y contadores

• El registro acumulador se inicializa a cero.

• El registro preset (dirección del acumulador – 1) se inicializa con el valor codificado.

La función de separar líneas guardó en el campo “parametro” del elemento los datos necesarios de la siguiente forma:

2 Bytes Dirección del acumulador codificada en hexadecimal (MSB LSB)

2 Bytes Valor de preset codificado en hexadecimal (MSB LSB)

Los opcodes afectados son: h4A, h49, h68 y h4F.

Temporizador con retardo a OFF

• El registro preset se inicializa con el valor codificado.

• El registro acumulador se inicializa con el valor del preset.

La función de separar líneas guardó en el campo “parámetro” del elemento los datos necesarios de la siguiente forma:

2 Bytes Dirección del acumulador codificada en hexadecimal (MSB LSB)

2 Bytes Valor de preset codificado en hexadecimal (MSB LSB)

Los opcodes afectados son: h42, h41 y h60.

Temporizadores de 0,01 segundo

Independientemente del tipo de temporizador, es necesario memorizar el número de línea y de elemento donde aparecen los temporizadores de 0,01 segundos, tal y como se comenta en el apartado 5.18.1.3 Bases de tiempo de temporizadores.

Los opcodes afectados son: h68 y h60.

Saltos a subrutina

En el apartado 4.2.3.8 Instrucciones de referencia de memoria se describe como la instrucción “Salto a subrutina” (opcode h4) se codifica con dos elementos, guardando el parámetro del segundo de ellos la posición de memoria de programa donde saltar.

Al no tener separado el código de programa en elementos si no en líneas, a diferencia del Logic Manager que guarda la posición en memoria del elemento siguiente al que codifica el comienzo de subrutina (opcode h24), el simulador va a guardar el número de la línea siguiente a la que contiene la instrucción “Subrutina” (opcode h14).

Para ello es necesario realizar dos lecturas del programa:

Page 283: DCSLLL

5 Programación

282

• Primera lectura: Determinar el número de línea en el que aparecen las instrucciones “subrutina” (opcode h24).

• Segunda lectura: Inicializar el campo “parametro” de las instrucciones “salto a subrutina” (opcode h4) con el número de línea siguiente a la línea que contiene la instrucción “subrutina”.

5.18.5.3. Function Fun_ExisteTimerRetentivo() As Boolean Evalúa todos los elementos que componen la línea y devuelve verdadero si existe un

temporizador retentivo en la línea actual.

• Timer retentivo base 1 sg: código h4E.

• Timer retentivo base 0,1 sg: código h4D.

• Timer retentivo base 0,01 sg: código h6C.

5.18.5.4. Function Fun_ExisteContador() As Boolean Evalúa todos los elementos que componen la línea y devuelve verdadero si existe un

contador (código h4F) en la línea actual.

5.18.6. Procedimientos y funciones de timers

5.18.6.1. Private Sub Sub_AñadirTimer001sg(Lng_NLinea As Long, Int_NElemento As Integer, Int_DireccionACC As Integer)

Este procedimiento comprueba si el timer con la dirección del acumulador indicada no ha sido memorizado todavía, y si no lo ha sido crea un nuevo registro en la tabla con la posición de todos los timers de 0,01 para poder actualizarlos a cada interrupción de 0,01 segundos.

Es llamado cada vez que en la lectura inicial del programa se detecta un elemento que codifica un timer de 0,01 segundos.

Flujograma Leer primer registro en la tabla (Tmr_Base001sg)

Coincide la dirección del acumulador con la parametrizada (Int_DireccionACC)?

Si Fin

… Repetir los tres últimos pasos para todos los registros (Tmr_Base001sg)

Crear nuevo registro

Rellenar campos: Alinea, NElemento, NDireccionACC

Fin

5.18.6.2. Private Sub Sub_DeterminarActualizarTimers001() Este procedimiento es ejecutado cada vez que se ejecuta una línea, para determinar si se

deben de actualizar los acumuladores de los temporizadores de base 0,01 segundos.

Documentación y decisiones En vez de implementar el código que actualice los acumuladores en este procedimiento,

éste se va a desarrollar en un procedimiento externo, pues se gana tiempo al no tener que crear y destruir las variables locales que éste necesita cuando la mayoría de las veces no hay que actualizarlos.

Page 284: DCSLLL

5 Programación

283

Flujogramas Han transcurrido 10 milisegundos desde la última actualización?

Si Poner a cero el tiempo transcurrido desde la última actualización.

Actualizar acumuladores (Sub_ActualizarTimers001sg)

Fin

5.18.6.3. Private Sub Sub_ActualizarTimers001sg() Este procedimiento es ejecutado cuando es necesario incrementar los acumuladores de

los timers de 0,01 segundos. Recorre cada uno de los temporizadores de 0,01 segundos del programa y si el temporizador está activo incrementa el acumulador.

Flujograma Leer línea de programa que contiene el timer (Fun_LeerRegistroLineaPrograma)

Leer elemento que codifica el timer

Hay que actualizar el acumulador (BitHistorico)?

Si Leer valor del acumulador (Fun_LeerRegistroMemUContenido16b)

Leer valor del preset (Fun_LeerRegistroMemUContenido16b)

Valor del acumulador < valor preset?

Si Incrementar valor del acumulador

Escribir valor del acum. (Sub_EscribirRegistroMemUContenido16b)

… Repetir para todos los timers memorizados (Tmr_Base001sg)

Fin

5.18.6.4. Private Sub Sub_DeterminarActualizarTimers01y1() Este procedimiento es ejecutado cada vez que se ejecuta un ciclo, para determinar si se

deben de actualizar los acumuladores de los temporizadores de base 0,1 y 1 segundo.

Flujogramas Han transcurrido 100 milisegundos desde la última actualización?

Si Poner a cero el tiempo transcurrido desde la última actualización.

Indicar que hay que actualizar acumuladores (Bool_ActualizarTimers01sg)

No Indicar que no hay que actualizar acum. (Bool_ActualizarTimers01sg)

Han transcurrido 1000 milisegundos desde la última actualización?

Si Poner a cero el tiempo transcurrido desde la última actualización.

Indicar que hay que actualizar acumuladores (Bool_ActualizarTimers1sg)

No Indicar que no hay que actualizar acum. (Bool_ActualizarTimers1sg)

Fin

5.18.7. Procedimientos y funciones saltos NSKR 8192-8447 Resumiendo lo expuesto en el capítulo 4.2.3.8 Instrucciones de referencia de memoria

se determina que es necesario almacenar la posición de memoria a la que tiene que saltar cada uno de los NSKR existentes en programa, en caso de ser activados.

Page 285: DCSLLL

5 Programación

284

Para guardar la posición se va a crear una tabla dinámica (Des_SaltosNSKR) que cuando exista un proyecto abierto estará compuesta por 256 registros, donde, el registro 0 guarda la posición de destino del salto número 8192 y el 255, la del 8447. Los campos de cada registro son:

• “Nlinea”: Número de línea de destino si se activa el salto.

• “Activo”: Indica si se ha evaluado una instrucción de fin de salto (EOS) activa.

5.18.7.1. Private Sub Sub_EscribirEstadoDestinoSaltoNSKR(Int_NSalto As Integer, Byte_Estado As Byte)

Escribe el estado del fin de salto NSKR de la línea actual

• En el caso de que no exista ningún EOS activo, el último EOS da igual que esté activo o no, es final de salto.

• Si hay dos finales de salto activos, el último es final de salto.

• Si hay dos finales de salto, para las siguientes secuencias de activación, una vez se ha activado el salto NSKR, el resultado es el siguiente:

- Primer EOS activo, último EOS no activo primer EOS fin de salto.

- Se activa último EOS último EOS fin de salto.

- Se desactiva último EOS último EOS fin de salto. No se vuelve al primer EOS como final de salto, para que la línea vuelva a ser evaluada.

Flujograma Ha existido un EOS activo anteriormente?

No Escribir en campo “Nlinea” el número de línea del EOS actual

El EOS actual está activo?

Si Escribir verdadero en el campo “Activo”

Si Indicar que no hay que actualizar acum. (Bool_ActualizarTimers1sg)

El EOS actual está activo?

Si Escribir en campo “Nlinea” el número de línea del EOS actual

Fin

5.18.7.2. Private Function Fun_NLineaDestinoSaltoNSKR(Int_NSalto As Integer) As Long

Devuelve el número de línea a la que debe de saltar la instrucción de salto directo NSKR (8192-8447), para ello devuelve el contenido del campo “Nlinea” del registro correspondiente (Número de salto – 8192) de la tabla Des_SaltosNSKR.

5.18.7.3. Private Sub Sub_SaltarLineas(Lng_NLineaInicio As Long, Lng_NLineaFin As Long)

Cuando se activa la instrucción de salto indirecto NSKR no es suficiente con saltar a la línea de destino. En las líneas saltadas se deben de inicializar los campos de estado e indicar que han sido saltadas (HaSidoSaltada=1), ya que la función Sub_SimularLinea encargada normalmente de esta función va a redireccionarse a la línea de destino.

Page 286: DCSLLL

5 Programación

285

Flujograma Inicializar estados de la linea saltada (Sub_InicializarEstadosLineaSaltada)

… Repetir el último paso con todas las líneas saltadas

Fin

5.18.8. Procedimientos y funciones de acceso a datos

5.18.8.1. Public Function Fun_LeerContenido16de1o16LSBConSigno(Int_Direccion As Integer) As Long

Devuelve el dato de 16 bits + 1 bit de signo contenido en la dirección especificada.

Si la dirección especificada corresponde a la zona de 1 bit (0-4095) el dato de 16 bits se obtiene de concatenar el contenido de las 16 direcciones de 1 bit consecutivas comenzando por la especificada, donde:

• Dirección especificada = bit de mayor peso.

• Dirección especificada - 15 = bit de menor peso.

En este caso el dato siempre es positivo al no existir bit de signo.

Si la dirección especificada corresponde a la zona de 16 bits + 1 bit de signo (4096-8191), el valor devuelto es el valor contenido.

Flujograma Direccion < 4096?

Si

Leer campo 1 bit de la dirección N (Fun_LeerRegistroMemUContenido1b)

Valor a devolver = valor anterior + (valor 1 bit x 215)

… Repetir los dos últimos pasos hasta alcanzar dirección N-15

No

Leer valor = campo 16bit dir. (Fun_LeerRegistroMemUContenido16b)

Leer signo = campo 1bitS dir. (Fun_LeerRegistroMemUContenido1b)

Valor a devolver = valor x signo

Fin

5.18.8.2. Private Sub Sub_EscribirContenido16en1o16LSBConSigno(Int_Direccion As Integer, ByVal Lng_Valor As Long)

Escribe el dato de 16 bits + 1 bit de signo, en la dirección especificada.

Si la dirección especificada corresponde a la zona de 1 bit (0-4095) el dato de 16 bits se escribe en 16 direcciones de 1 bit consecutivas comenzando por la especificada, donde:

• Dirección especificada = bit de mayor peso.

• Dirección especificada - 15 = bit de menor peso.

En este caso se deprecia el signo.

Si la dirección especificada corresponde a la zona de 16 bits + 1 bit de signo (4096-8191), el valor escrito es el valor especificado.

Page 287: DCSLLL

5 Programación

286

Flujograma Direccion < 4096?

Si

Obtener el resto de dividir el valor recibido / 2

Escribir el resto en el campo 1bitS de la dirección N

… Repetir los dos últimos pasos hasta alcanzar dirección N-15

No Valor < 0?

Si Escribir 1 en el campo 1bitS de la dirección (signo negativo)

No Escribir 0 en el campo 1bitS de la dirección (signo positivo)

Escribir valor absoluto en el campo 16 bit de la dirección

Fin

5.18.9. Procedimientos y funciones de evolución de direcciones

5.18.9.1. Public Sub Sub_RellenarBinomiosEvolucionDirecciones() Decodifica las cadenas de texto con las expresiones de evolución contenidas en la tabla

“Evolucion” de la base de datos, escribiendo los binomios “Tiempo, Valor” que corresponden a cada dirección en los registros de tres tablas: Evo_TablaE1b, Evo_TablaS1b y Evo_Tabla16b.

Flujograma Filtrar en tabla “Evolucion” solo registros con expresiones de evolución

(Sub_CambiarFiltroEvolucion)

Leer primer registro (Fun_LeerRegistroEvolucionPorPosicion)

Existe una expresión de evolución de entrada de 1 bit?

Si Obtener campo “Tiempo” del primer binomio

Obtener campo “Valor” del primer binomio

Escribir en un nuevo registro los datos obtenidos

… Repetir los cinco últimos pasos hasta finalizar todos los binomios

Escribir el registro en la tabla de evolución de estados de entrada de 1 bit (Sub_EscribirRegistroEvolucionTablaE1bPorPosicion)

Existe una expresión de evolución de salida de 1 bit?

Si Obtener campo “Tiempo” del primer binomio

Obtener campo “Valor” del primer binomio

Escribir en un nuevo registro los datos obtenidos

… Repetir los cinco últimos pasos hasta finalizar todos los binomios

Escribir el registro en la tabla de evolución de estados de salida de 1 bit (Sub_EscribirRegistroEvolucionTablaS1bPorPosicion)

Existe una expresión de evolución de 16 bits?

Si Obtener campo “Tiempo” del primer binomio

Page 288: DCSLLL

5 Programación

287

Obtener campo “Valor” del primer binomio

Escribir en un nuevo registro los datos obtenidos

… Repetir los cinco últimos pasos hasta finalizar todos los binomios

Escribir el registro en la tabla de evolución de estados de 16 bits (Sub_EscribirRegistroEvolucionTabla16bPorPosicion)

Fin

5.18.9.2. Public Sub Sub_EscribirRegistroEvolucionTablaE1bPorPosicion(Int_Posicion As Integer, Evo_Actual1b As EvolucionEntrada1b)

Escribe el registro de evolución en la tabla de evolución de estados de entrada de 1b en la posición indicada.

Si la posición indicada es cero, el procedimiento crea un nuevo registro donde escribe el registro recibido. En cualquier otro caso, como siempre va a existir la posición parametrizada, no es necesario un control de error.

Flujograma La posición indicada es cero?

Si Añadir nuevo registro

No Editar registro existente

Fin

IDEM para procedimientos:

• Public Sub Sub_EscribirRegistroEvolucionTablaS1bPorPosicion(Int_Posicion As Integer, Evo_Actual1b As EvolucionEntrada1b)

• Public Sub Sub_EscribirRegistroEvolucionTabla16bPorPosicion(Int_Posicion As Integer, Evo_Actual16b As EvolucionEntrada16b)

5.18.9.3. Private Sub Sub_LeerValorActualEstadoE16b(Int_Direccion As Integer) Actualiza el valor del campo de 16 bits que le corresponde a la dirección indicada del

rango 0-2047, según los binomios de evolución para el tiempo actual de ejecución.

Se encarga por tanto de simular el acceso de la instrucción “PULL” a la zona de estados de entrada de 16 bits.

Flujograma Existe el registro con la dirección indicada?

No Devolver cero

Fin

Si Recuperar índice del primer binomio no evaluado

Leer binomio

Tiempo actual de ejecución mayor o igual al campo “Tiempo” del regisro

Si Indicar binomio encontrado

No Abandonar el bucle

… Repetir los cuatro últimos pasos hasta evaluar último registro

Page 289: DCSLLL

5 Programación

288

Escribir campo “Valor” en el campo 16 bits de la tabla de memoria de usuario (Sub_EscribirRegistroMemUContenido16b)

Actualizar el registro de evolución con el índice del último registro accedido (Sub_EscribirRegistroEvolucionTabla16bPorPosicion)

Fin

5.18.9.4. Private Sub Sub_ISS() Actualiza las direcciones de las tablas de memoria de usuario con el valor del binomio

correspondiente para el tiempo en curso de las tablas de evolución:

• Tabla de estados de entrada de 1 bit al comienzo del ciclo.

• Tabla de estados de salida de 1 bit y tabla de registros de 16 bits al comienzo del ciclo siguiente a que hayan transcurrido ½” desde la última actualización.

Este procedimiento realiza las acciones del procedimiento anterior con cada una de las tres tablas.

Flujograma Acciones para la tabla de estados de entrada de 1 bit (Evo_TablaE1b)

Comienzo de ejecución?

Si Temporizador a cero

Ha transcurrido ½” desde la última actualización?

Si Temporizador a cero

Acciones para la tabla de estados de salida de 1 bit (Evo_TablaS1b)

Acciones para la tabla de estados de registro de 16 bits (Evo_Tabla16b)

Fin

Page 290: DCSLLL

6 Manual de usuario

289

6. Manual de usuario 6.1. Descripción

El programa SLM trabaja con los archivos generados por el programa MS-DOS Loader y permite:

• Editar los datos de los archivos de documentación.

• Visualizar el programa lógico en escalera exceptuando las instrucciones matriciales y de secuenciador.

• Simular los programas lógicos diseñados para los equipos Logic Manager con procesador modelo 620-25 y 620-35.

Este manual, describe exclusivamente el funcionamiento de cada una de las opciones del programa SLM y no el funcionamiento del Logic Manager ni su lenguaje de programación. Si el usuario no tiene dichos conocimientos, debe consultar los capítulos previos o referirse a la documentación del LM para adquirirlos.

6.2. Instalación En el CD de instalación se encuentran tres archivos: “Setup.exe”, “Setup.lst” y

“SLM.cab”.

Para realizar la instalación hay que cerrar las aplicaciones abiertas, ejecutar el programa “Setup.exe” y seguir los pasos que se indican.

El archivo temporal que requiere el programa para almacenar los datos del proyecto abierto, se crea en la ruta establecida por el sistema para almacenar los archivos temporales con el nombre “slm.mdb”.

6.3. Comienzo del programa El siguiente paso es ejecutar el programa “SLM.exe” que estará almacenado en la ruta

especificada durante la instalación.

El programa comienza presentando durante dos segundos la ventana de información, mientras en segundo plano continúa la carga de la ventana principal.

Figura 67. Ventana de presentación

La ventana principal y las secundarias trabajan de la siguiente forma:

Page 291: DCSLLL

6 Manual de usuario

290

• Tanto la ventana principal como las ventanas secundarias guardan el último tamaño y posición.

• Las ventanas de selección de fichero guardan la última ruta accedida.

Figura 68. Componentes de la ventana principal

6.4. Apertura de un proyecto Si no existe un proyecto abierto, todas las opciones del menú y de la barra de

herramientas quedan inhabilitadas excepto las opciones “Abrir” y “Salir” del menú “Proyecto”.

Figura 69. Menú sin proyecto abierto

Menú

Barra de herramientas

Ventana secundaria

Barra de progreso Barra de estado

Ventana principal

Page 292: DCSLLL

6 Manual de usuario

291

6.4.1. Menú Proyecto

6.4.1.1. Abrir Permite al usuario abrir un nuevo proyecto.

Presenta la ventana de selección del fichero *.cfg, donde poder explorar las unidades de disco hasta encontrar el fichero deseado. Si el usuario confirma la selección con el botón Aceptar, se abren y decodifican los ficheros de configuración, de programa y de documentación asociados al archivo de configuración.

Un error en el archivo de configuración se considera crítico, por lo que se aborta la apertura del proyecto apareciendo un aviso de error. Si el error se presenta en cualquiera de los archivos asociados, se abandona el archivo actual y la carga continúa con el archivo siguiente.

Si el proyecto seleccionado corresponde a los modelos 620-25 y 620-35 se habilitan todas las opciones del menú y de la barra de herramientas. Si corresponde a otros modelos se impide la simulación, por lo que la barra de herramientas y las opciones del menú “Ver”: “Simulación” y “Mapeado de memoria” permanecen inhabilitadas.

6.4.1.2. Salir Se cierra el programa.

6.5. Trabajando con un proyecto Este capítulo describe el funcionamiento de cada una de las opciones del menú y de la

barra de herramientas cuando existe un proyecto abierto de un modelo que permite la simulación.

6.5.1. Menú Proyecto Agrupa los comandos relacionados con la gestión del proyecto.

Figura 70. Menú Proyecto

6.5.1.1. Abrir

Pregunta si se desean guardar los cambios realizados en el proyecto abierto antes de cerrarlo. En caso afirmativo presenta una ventana donde el usuario puede seleccionar que archivos actualizar (ver capítulo 6.5.1.4 Guardar uno a uno).

Una vez se ha cerrado el proyecto, el funcionamiento es el mismo que el descrito en el apartado 6.4.1.1 Abrir.

Page 293: DCSLLL

6 Manual de usuario

292

6.5.1.2. Cerrar Pregunta si se desean guardar los cambios realizados en el proyecto antes de cerrarlo.

En caso afirmativo presenta una ventana donde el usuario puede seleccionar que archivos actualizar (ver capítulo 6.5.1.4 Guardar uno a uno).

6.5.1.3. Editar Ejecuta el programa MS-DOS Loader con el archivo de configuración del proyecto

actual, para facilitar al usuario la edición del programa.

Esta opción sólo funcionará si el programa MS-DOS Loader (Loader.exe) se encuentra en la misma ruta que el archivo de configuración del proyecto abierto y está habilitado el acceso de escritura en dicha ruta.

Después de la modificación, será necesario volver a abrir el proyecto actual para que se actualicen los cambios.

6.5.1.4. Guardar uno a uno Presenta una ventana donde el usuario puede seleccionar qué archivos actualizar con los

cambios realizados en el programa.

Además de los archivos asociados al proyecto actual (los 8 primeros), existe la posibilidad de guardar el archivo “Entorno de simulación”, que se escribirá con la misma ruta y nombre que los archivos de documentación utilizando la extesión “slm”. Este archivo contiene los parámetros que configuran la simulación (ver capítulo 6.5.2.4 Simulación).

No se permite seleccionar el fichero de líneas de programa por no ser editable.

Figura 71. Ventana guardar uno a uno

6.5.1.5. Guardar todos A diferencia del comando anterior, se actualizan todos los archivos listados con los

cambios realizados en el programa.

6.5.1.6. Salir

Solicita al usuario que confirme que realmente desea abandonar el programa. En caso afirmativo permite guardar los cambios realizados en el proyecto abierto antes de cerrarlo (ver capítulo 6.5.1.4 Guardar uno a uno).

Page 294: DCSLLL

6 Manual de usuario

293

6.5.2. Menú Ver Agrupa los comandos relacionados con la gestión de las ventanas secundarias.

Figura 72. Menú Ver

Al seleccionar una opción, se abre la ventana secundaria asociada. Hasta que se cierre dicha ventana, la opción correspondiente presentará el símbolo .

Para cerrar la ventana se puede pulsar el botón en la esquina superior derecha de la misma, o volver a seleccionar la opción correspondiente del menú “Ver”.

Si una ventana está oculta por otra y el usuario desea hacerla visible se puede o bien cerrar y abrir la ventana, o ponerla en primer plano utilizando el menú “Ventana” (ver capítulo 6.5.3).

6.5.2.1. Programa Esta ventana permite la visualización de las líneas de programa.

Mediante una barra de desplazamiento vertical, el usuario selecciona la primera línea a visualizar, completándose la pantalla con las líneas siguientes si las hubiese.

Para facilitarle la operación al usuario, mientras se arrastra el deslizador, un recuadro de texto informa de la primera línea que será visualizada.

Figura 73. Ventana de programa

Funcionamiento en modo normal

Si no se está depurando el programa, el comportamiento de la ventana es el siguiente.

Page 295: DCSLLL

6 Manual de usuario

294

Información de línea

Figura 74. Información de línea

Las celdas de la primera columna aportan la siguiente información:

• Número de línea.

• Número del comentario de línea entre paréntesis si lo tuviese.

Al seleccionar con el ratón una celda de la primera columna, aparece un recuadro de texto con la información de los archivos de documentación relacionados:

• Texto del comentario de línea.

Para ocultar el recuadro de texto basta con pulsar sobre él mismo, el botón izquierdo del ratón.

Información de elemento

Figura 75. Información elemento

Al seleccionar con el ratón una celda de la zona de elementos, aparece un recuadro de texto con la información de los archivos de documentación relacionados en función del tipo de elementos seleccionado:

• Dirección: Texto de la etiqueta y del comentario de dirección.

• Bit: Texto de la etiqueta y del comentario de dirección.

• Salto: Texto de la etiqueta.

• Subrutina: Texto de la etiqueta.

Para ocultar el recuadro de texto basta con pulsar sobre el mismo, el botón izquierdo del ratón.

Elementos forzados

Los elementos forzados se visualizan con un color distinto:

• Forzado a ON: ROJO.

• Forzado a OFF: AZUL.

Page 296: DCSLLL

6 Manual de usuario

295

Funcionamiento en Modo depuración Además de las opciones ya descritas en modo normal, si se está depurando el programa

ya sea línea a línea o ciclo a ciclo, una vez se acaba de ejecutar el comando de depuración en curso, la ventana se refresca con información adicional que permite al usuario observar la evolución de la ejecución.

Seguimiento de la evolución

La información adicional es la siguiente:

• Las celdas de la primera columna añaden las siguientes cadenas de texto para indicar dos situaciones:

- “No ejec”: La línea no ha sido ejecutada bien porque el usuario ha usado el botón “No ejecutar línea”, o la línea no se encuentra dentro del rango de líneas a simular (ver capítulo 6.5.2.4 Simulación).

- “Saltada”: La línea se encuentra dentro de un bloque de salto NSK activo.

• Se colorea en verde la secuencia lógica verdadera a lo largo de las formaciones serie o paralelo que forman la línea de programa.

• En los elementos que trabajan con valores enteros, si el elemento es de entrada, presenta debajo del mismo el valor que tenía antes de realizar la operación. Si es de salida presenta el valor resultante de la operación.

• El recuadro de texto inferior, indica el tiempo en microsegundos transcurridos desde el comienzo de la ejecución.

Visualización automática de la última línea ejecutada

Si el usuario marca la casilla de selección de la esquina inferior-izquierda, la ventana visualiza automáticamente la última línea ejecutada con cada orden de depuración, en caso contrario, se refrescan las líneas mostradas con los nuevos datos.

6.5.2.2. Configuración

Esta ventana permite visualizar los datos del archivo de configuración. Sólo son editables los parámetros relacionados con el programa SLM. Cada una de las pestañas da acceso a un grupo de parámetros. Para saber qué hace cada parámetro es necesario referirse a la documentación técnica del programa MS-DOS Loader.

Page 297: DCSLLL

6 Manual de usuario

296

Los cambios realizados no serán efectivos hasta que el usuario los confirme o bien con el botón “Aceptar” o el botón “Aplicar”.

Paths and Files Los cuatro primeros parámetros establecen la ruta y el nombre de los archivos de

programa y de documentación.

Figura 76. Ventana de configuración – Paths and Files

Operacional Modes

Figura 77. Ventana de configuración – Operational Modes

Page 298: DCSLLL

6 Manual de usuario

297

System Type and File Loads

Figura 78. Ventana de configuración – System Type and File Loads

Stand-Alone Parameters Al seleccionar un modelo distinto de procesador, cambian las opciones de configuración

del mapeado de memoria.

Figura 79. Ventana de configuración – Stand-Alone Parameters

Seleccionar un modelo distinto a 620-25 o 620-35 inhabilita la simulación (ventanas “Simulación” y “Mapeado de memoria” así como la barra de herramientas).

Los cambios realizados en el mapeado de memoria, redimensionan las tablas de las ventanas “Simulación” y “Mapeado de memoria”. En ambos casos, se mantienen los valores que tenían los registros que no se vean afectados en el redimensionamiento.

6.5.2.3. Documentación Esta ventana permite editar los datos de los archivos de documentación.

Page 299: DCSLLL

6 Manual de usuario

298

Los cambios en un registro son efectivos cuando se cambia a otro registro o se abandona la tabla de edición. Sin embargo, para que se reflejen en la ventana de programa, es necesario redibujar las líneas visualizadas (mover una línea arriba o abajo).

Figura 80. Ventana de documentación

Edición de los datos Cada una de las pestañas da acceso a los datos de un archivo:

• Address label: archivo *.lbl (etiquetas de dirección)

• Address comment: *.ace (comentarios de dirección)

• Line comment: *.lce (comentarios de líneas de programa)

• Skip label: *.skp (etiquetas de líneas de salto)

• Subroutine label: *.jsr (etiquetas de líneas de subrutina)

• Bit Comment: *.bce (comentarios de bit)

• Bit label: *.blb (etiquetas de bit)

Pestañas de Etiquetas

El programa evita que se introduzcan valores incorrectos en las celdas:

• NUMERO: Los rangos válidos son:

- Dirección: 0-8191

- Salto: 0-32767

- Subrutina: 0-255

- Bit: 0-65535

• ETIQUETA: La cadena de texto no puede exceder los 7 caracteres.

• DESCRN#: La cadena de texto no puede exceder los 9 caracteres.

Si se introduce un valor incorrecto, después de la ventana de advertencia la celda recupera el último valor correcto.

Page 300: DCSLLL

6 Manual de usuario

299

Pestañas de Comentarios

El programa evita que se introduzcan valores incorrectos en las celdas:

• NUMERO: Los rangos válidos son:

- Dirección: 0-8191

- Línea: 0-32767

- Bit: 0-65535

• TEXTO: La cadena de texto no puede exceder de 1340 caracteres (20 líneas x 67 caracteres).

Si se introduce un valor incorrecto, después de la ventana de advertencia la celda recupera el último valor correcto.

Localización rápida de un registro Para poder localizar de forma rápida un registro, se dispone del recuadro de texto “Ir a”.

La pestaña seleccionada mostrará la etiqueta o el comentario cuyo campo “NUMERO” coincida con el valor escrito por el usuario. Si el registro solicitado no existe, se mantiene el último registro seleccionado.

Exportar/Importar los datos en una base de datos El usuario puede editar los datos de los archivos de documentación de forma externa al

programa, exportando los datos en una base de datos formato Microsoft Access 2000.

La base de datos creada contiene 8 tablas: siete tablas que corresponden a las cuatro tablas de etiquetas y las tres tablas de comentarios ya mencionadas y la tabla “Evolucion” con las expresiones de evolución de las direcciones de entrada (ver capítulo 6.5.2.4 Simulación).

Al modificar los datos externamente el programa SLM no controla los datos que el usuario introduce, por lo que el usuario debe de evitar introducir errores.

6.5.2.4. Simulación Esta ventana permite configurar la simulación. Si el modelo de procesador no es 620-25

ó 620-35 permanece inhabilitada.

Page 301: DCSLLL

6 Manual de usuario

300

Figura 81. Ventana de simulación

Parámetros de simulación La parte superior de esta ventana, permite editar los parámetros de configuración de la

simulación, disponiendo del botón “Aplicar” para validar los cambios y del botón “Restaurar” para cancelarlos y recuperar los valores anteriores.

Líneas a simular

Permite seleccionar que líneas se desean simular. De esta forma se pueden simular las partes del programa que en verdad interesen.

La forma en que el usuario debe de indicar las líneas es la siguiente:

• Selección de líneas sueltas: “1,2,6” implica ejecutar líneas 1, 2 y 6.

• Selección de rangos de líneas: “1-3” implica ejecutar líneas 1, 2 y 3.

• Combinación de ambos estilos: “1,4-6,9” implica ejecutar líneas 1, 4, 5, 6 y 9.

• La celda en blanco equivale a simular todas las líneas.

Tiempo de simulación

Existen tres parámetros:

• Tiempo estimado de la duración de ejecutar un ciclo (µs).

• Tiempo total de simulación (µs).

• Número total de ciclos a simular.

Definiendo dos de ellos, el tercero queda determinado de acuerdo a la siguiente fórmula:

Tiempo total = Tiempo de ciclo x Número de ciclos

Page 302: DCSLLL

6 Manual de usuario

301

En cualquier momento a lo largo de la simulación se pueden cambiar el valor de los tres parámetros. Así, por ejemplo, una vez alcanzado el final de la simulación, puede aumentar tanto el tiempo total como el número de ciclos para continuar la simulación actual sin necesidad de reiniciar.

Sin embargo, para mantener la coherencia y no visualizar señales con distintas bases de tiempo, a pesar de que se acepten los cambios en el tiempo de ejecución de un ciclo, éste no tendrá efecto hasta reiniciar.

Evolución de las direcciones La parte central, permite configurar la evolución de las direcciones.

Expresiones de evolución de las direcciones de entrada

La tabla izquierda permite introducir las expresiones de evolución de las direcciones de la tabla de estados E/S y de la tabla de registros.

Basta con escribir la evolución en el campo correspondiente de la dirección deseada respetando el siguiente formato:

Tiempo, Valor; Tiempo, Valor; …

Tiempo: Momento de cambio expresado en microsegundos.

Valor para registros de 1 bit: 0, 1.

Valor para registros de 16 bits: 0-65535.

Las expresiones de evolución pueden ser editadas de forma externa en una base de datos, usando la función de exportación de la ventana de documentación (ver capítulo 6.5.2.3).

Seleccionar direcciones de salidas de las que seguir la evolución

La lista derecha contiene las direcciones de 1 bit de las que guardar la evolución a lo largo de la simulación.

Los cuatro botones realizan las siguientes funciones:

• Añade a la lista en la posición siguiente a la actual, la dirección del registro seleccionado en la tabla de expresiones de evolución.

• Elimina la dirección seleccionada en la lista. La posición anterior pasa a ser la actual.

• Reordena subiendo una posición la dirección seleccionada.

• Reordena bajando una posición la dirección seleccionada.

La representación de los cronogramas se va a realizar en el orden en que aparecen las direcciones en la lista, es por ello que se permite introducir una dirección en distintas posiciones.

Para poder visualizar el cronograma de una dirección es necesario que la dirección estuviese en la lista al comenzar la simulación. Si se hecha en falta una dirección una vez comenzada la simulación, hay que reiniciar la simulación después de añadir la nueva dirección en la lista.

Sin embargo, una vez iniciada la simulación, se puede reordenar la lista e incluso repetir una dirección de las ya existentes en otra posición.

Page 303: DCSLLL

6 Manual de usuario

302

Cronogramas La parte inferior, presenta los cronogramas de la evolución de las direcciones

seleccionadas en la lista superior.

El valor mostrado es el resultado de realizar una OR entre los valores del campo de 1Bit E y 1Bit S.

Si se intenta visualizar el cronograma de una dirección añadida a la lista después de que esta haya comenzado, aparece el mensaje “No existe historial de esta dirección. Volver a generar”.

Intervalo de visualización El usuario puede seleccionar el intervalo de tiempo que le interesa representar,

indicando el tiempo de inicio y el de fin en microsegundos.

Grid Automático o Manual

Utilizando la casilla “Grid Aut/Man” el usuario puede elegir entre definir el tiempo entre las líneas de división verticales (Manual), o dejar que el programa calcule el número de divisiones (Automático).

6.5.2.5. Mapeado de memoria Esta ventana permite editar los valores de los campos de las tablas de memoria de

usuario y de sistema. Si el modelo de procesador no es 620-25 o 620-35 permanece inhabilitada.

Figura 82. Ventana de mapeado de memoria

Edición de los datos

Los registros que componen cada una de las tablas vienen determinados por los parámetros de configuración del mapeado de memoria (ver capítulo 6.5.2.2

Page 304: DCSLLL

6 Manual de usuario

303

Configuración), por lo que el usuario no puede ni borrar ni crear nuevos registros, sólo modificar los valores de los campos dentro de los rangos especificados:

• 1B E: 0-1

• 1B S: 0-1

• 16BITS: 0-65535

• 8BITS: 0-255

Localización rápida de un registro Para poder localizar de forma rápida un registro, se dispone del recuadro de texto “Ir a”.

La tabla mostrará la dirección cuyo campo “NUMERO” coincida con el valor escrito por el usuario. Si el registro solicitado no existe, se mantiene en el último registro seleccionado.

6.5.3. Menú Ventana Agrupa los comandos relacionados con la organización de las ventanas secundarias.

Figura 83. Menú Ventana

6.5.3.1. Cascada Pone en cascada todas las ventanas secundarias abiertas no minimizadas.

6.5.3.2. Mosaico horizontal

Crea un mosaico horizontal con todas las ventanas secundarias abiertas no minimizadas.

6.5.3.3. Mosaico vertical Crea un mosaico vertical con todas las ventanas secundarias abiertas no minimizadas.

6.5.3.4. Organizar iconos Organiza los iconos de las ventanas secundarias abiertas minimizadas.

6.5.3.5. Ventanas secundarias abiertas En la parte inferior del menú, se listan todas las ventanas secundarias abiertas,

marcándose con el símbolo la ventana con la que se está trabajando (ventana activa). Si el usuario selecciona cualquier ventana de la lista, ésta pasará a ser la ventana activa.

6.5.4. Barra de herramientas La barra de herramientas permite al usuario seleccionar fácilmente la forma en que

quiere ejecutar el programa, ya sea paso a paso o de forma contínua. Si el modelo de procesador no es 620-25 o 620-35 permanece inhabilitada.

Page 305: DCSLLL

6 Manual de usuario

304

La simulación se realiza de acuerdo al valor de los parámetros de simulación (ver capítulo 6.5.2.4 Simulación). Por ello, la simulación finalizará cuando se alcance el tiempo de fin de simulación.

6.5.4.1. Ejecutar siguiente línea Ejecuta la siguiente línea del programa.

Si la línea en cuestión no corresponde al rango de líneas que se desean simular, automáticamente se salta y se avanza a la siguiente línea hasta encontrar una que sí que corresponda.

6.5.4.2. No ejecutar siguiente línea Salta la siguiente línea del programa sin ejecutarla.

La celda con la información de la línea saltada en la ventana “Programa” muestra el texto “No ejec” para indicar esta situación.

Si la línea en cuestión no corresponde al rango de líneas que se desean simular, automáticamente se salta y se avanza a la siguiente línea hasta encontrar una que sí que corresponda.

6.5.4.3. Ejecutar un ciclo Se completa un ciclo de programa.

Si se selecciona esta orden cuando se han ejecutado líneas utilizando las ordenes de depuración anteriores, este comando acaba la ejecución del ciclo actual.

6.5.4.4. Ejecución contínua Se ejecuta el programa hasta alcanzar el tiempo de fin de simulación.

6.5.4.5. Reiniciar ejecución Reinicia (se borran los datos) la simulación actual.

Básicamente reinicia el contador de tiempo.

Page 306: DCSLLL

6 Manual de usuario

305

7. Conclusiones Después de haber desarrollado el programa objetivo del proyecto, se concluyen los

siguientes puntos.

Para poder diseñar el simulador de cualquier elemento, no sólo el de un automáta programable, es imprescindible tener total acceso al elemento, para así poder realizar las pruebas necesarias que aclaren las dudas que con toda seguridad aparecerán a lo largo del desarrollo.

El Logic Manager es un autómata programable todavía disponible en el mercado, pero desarrollado hace muchos años. Esta particularidad ha facilitado el desarrollo del simulador, pues sin tener acceso a información privilegiada, se han podido decodificar los archivos asociados, gracias a la sencillez con que fueron diseñados.

Antes de comenzar este proyecto, se estudió realizar el simulador de otro elemento del sistema de control disitribuido llamado FSC (Fail Safe Controller), elemento mucho más moderno que pretende sustituir al Logic Mnager en alguna de sus funciones. Sin embargo, se observó como los archivos relacionados presentaban la información codificada, de tal forma que sin tener acceso a información privilegiada parecía imposible poder desarrollar un simulador.

Los diseñadores del Logic Manager, consiguieron diseñar un sistema robusto y fiable partiendo de diseños simples, que utilizaban los mínimos recursos tanto de memoria como de procesamiento. Con los casi ilimitados recursos disponibles actualmente, se hace difícil desarrollar sistemas que aprovechen al 100% los recursos utilizados.

Aunque el programa diseñado realiza correctamente las funciones que incorpora, no cabe duda que puede mejorarse en los siguientes puntos.

• Lo más importante es solucionar las dudas (párrafos marcados con el símbolo ? a lo largo de los capítulos) que por no disponer de Logic Manager para realizar las pruebas han quedado sin resolver y que han tenido que ser implementadas bajo suposiciones. Recordemos que uno de los objetivos del proyecto era aclarar el funcionamiento de todas las instrucciones de los modelos 620-25/35, que por la razón expuesta no ha podido ser completado.

• Añadir en la ventana de visualización de líneas de programa, funciones de búsqueda de direcciones, instrucciones…, que facilitarían en gran medida el trabajo del programador mientras está simulando el programa.

• Incorporar un editor de las líneas de programa. Aunque el programa MS-DOS Loader realiza esta función de forma más que correcta y el programa desarrollado permite llamarlo directamente, también es cierto que luego es necesario cerrar y volver a abrir el proyecto actual para refrescar los cambios. Sería mucho más rápido y efectivo, si mientras se está simulando se pudiesen introducir cambios en las líneas de programa a medida que se detectan los errores, de tal forma que no hubiese que reiniciar la simulación perdiendo el contexto en que se encontró el error.

• Actualizar automáticamente el área de registros de estado del sistema.