Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL...

247
Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL SIMPLE Autor: Félix Robles Elvira Tutor: José Ángel Acosta Rodríguez Ingeniería de Telecomunicación Departamento de Ingeniería de Sistemas y Automática Escuela Técnica Superior de Ingeniería Universidad de Sevilla

Transcript of Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL...

Page 1: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Proyecto Fin de Carrera

EMULADOR DECOMPUTADOR DIGITAL

SIMPLE

Autor: Félix Robles ElviraTutor: José Ángel Acosta Rodríguez

Ingeniería de TelecomunicaciónDepartamento de Ingeniería de Sistemas y Automática

Escuela Técnica Superior de IngenieríaUniversidad de Sevilla

Page 2: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.
Page 3: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Dedicado a mis padres, a mis hermanos, a mi tutor José Ángel Acosta Rodríguez

por su ayuda, y a todos los amigos y familiares a los que les guste que les dediquen

proyectos �n de carrera.

Page 4: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Índice

1. Introducción y objetivos 1

2. Elección del lenguaje de programación a usar 3

3. Fundamentos de un computador digital 5

3.1. Codi�cación binaria de la información . . . . . . . . . . . . . . . . . . . 5

3.1.1. Numeraciones binaria y decimal . . . . . . . . . . . . . . . . . . 5

3.1.2. Codi�cación de números enteros . . . . . . . . . . . . . . . . . . 6

3.2. Codi�cación de caracteres . . . . . . . . . . . . . . . . . . . . . . . . . 7

3.3. Álgebra de boole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3.3.1. De�nición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.3.2. Propiedades del álgebra de boole . . . . . . . . . . . . . . . . . 11

3.3.3. Funciones booleanas . . . . . . . . . . . . . . . . . . . . . . . . 11

3.3.4. Puertas lógicas . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

4. Estructura general de un computador digital 15

4.1. Arquitectura de Von Neumann . . . . . . . . . . . . . . . . . . . . . . . 15

4.2. Almacenamiento de la información . . . . . . . . . . . . . . . . . . . . 16

4.3. Unidad de memoria central . . . . . . . . . . . . . . . . . . . . . . . . . 19

4.4. Unidad aritmético-lógica . . . . . . . . . . . . . . . . . . . . . . . . . . 21

4.5. Unidad de entrada y salida . . . . . . . . . . . . . . . . . . . . . . . . . 22

4.6. Enlaces o buses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

4.7. Unidad de control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

5. Descripción de la máquina a implementar 27

5.1. Elementos del computador . . . . . . . . . . . . . . . . . . . . . . . . . 27

5.2. Funcionamiento del computador . . . . . . . . . . . . . . . . . . . . . . 29

5.2.1. Ejecución de instrucciones . . . . . . . . . . . . . . . . . . . . . 31

5.2.2. Instruciones de salto . . . . . . . . . . . . . . . . . . . . . . . . 33

5.2.3. Funcionamiento de la unidad de control . . . . . . . . . . . . . . 34

5.3. Código máquina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

5.4. Lenguaje ensamblador . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

5.5. Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

5.5.1. Media de tres números . . . . . . . . . . . . . . . . . . . . . . . 40

4

Page 5: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

5.5.2. Cálculo de número primo . . . . . . . . . . . . . . . . . . . . . . 41

5.5.3. Módulo al cuadrado de un vector . . . . . . . . . . . . . . . . . 43

5.5.4. Frase o palabra en orden inverso . . . . . . . . . . . . . . . . . . 44

5.5.5. Lectura de una matriz . . . . . . . . . . . . . . . . . . . . . . . 46

5.5.6. Submatriz triangular . . . . . . . . . . . . . . . . . . . . . . . . 48

6. Estructura del emulador 53

6.1. Código ensablador y código binario . . . . . . . . . . . . . . . . . . . . 53

6.2. Clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

6.2.1. Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

6.2.2. ProjectsManager . . . . . . . . . . . . . . . . . . . . . . . . . . 58

6.2.3. TabsManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

6.2.4. DebugViewManager . . . . . . . . . . . . . . . . . . . . . . . . 61

6.2.5. Sobre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

6.2.6. Emulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

6.2.7. VirtualComputer . . . . . . . . . . . . . . . . . . . . . . . . . . 69

6.2.8. ButtonTabComponent . . . . . . . . . . . . . . . . . . . . . . . 71

6.2.9. XenonHelper . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

6.2.10. LineCode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

6.2.11. Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

6.2.12. PopupListener . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

6.2.13. Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

6.2.14. ProjectFile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

6.2.15. Tab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

6.2.16. JConnector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

6.2.17. ConnectorContainer . . . . . . . . . . . . . . . . . . . . . . . . 80

6.2.18. ConnectLine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

7. Manual de usuario 83

7.1. Ejecución . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

7.2. Vista de desarrollo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

7.3. Vista de emulación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

7.4. Vista de depuración . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

5

Page 6: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

8. Posibles ampliaciones 91

8.1. Interfaz grá�ca para plataformas móviles . . . . . . . . . . . . . . . . . 91

8.2. Ampliación del juego de instrucciones del computador . . . . . . . . . . 95

9. Conclusiones y cumplimiento de objetivos 103

10.Bibliografía 105

11.Anexos 107

11.1. Código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

11.1.1. ButtonTabComponent.java . . . . . . . . . . . . . . . . . . . . . 107

11.1.2. JConnector.java . . . . . . . . . . . . . . . . . . . . . . . . . . 109

11.1.3. Emulator.java . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

11.1.4. ConnectLine.java . . . . . . . . . . . . . . . . . . . . . . . . . . 120

11.1.5. LineCode.java . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

11.1.6. Sobre.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

11.1.7. ConnectorContainer.java . . . . . . . . . . . . . . . . . . . . . 128

11.1.8. PopupListener.java . . . . . . . . . . . . . . . . . . . . . . . . . 129

11.1.9. Tab.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

11.1.10.DebugViewManager.java . . . . . . . . . . . . . . . . . . . . . 132

11.1.11.ProjectFile.java . . . . . . . . . . . . . . . . . . . . . . . . . . 159

11.1.12.TabsManager.java . . . . . . . . . . . . . . . . . . . . . . . . . 160

11.1.13.Project.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

11.1.14.VirtualComputer.java . . . . . . . . . . . . . . . . . . . . . . . 166

11.1.15.Instruction.java . . . . . . . . . . . . . . . . . . . . . . . . . . . 208

11.1.16.ProjectsManager.java . . . . . . . . . . . . . . . . . . . . . . . 213

11.1.17.XenonHelper.java . . . . . . . . . . . . . . . . . . . . . . . . . . 217

11.1.18.Interface.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

6

Page 7: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Índice de �guras

1. Vista del gestor de versiones del software . . . . . . . . . . . . . . . . . 4

2. Circuito de la suma de a y b . . . . . . . . . . . . . . . . . . . . . . . . 10

3. Circuito simbólico del producto de a y b . . . . . . . . . . . . . . . . . 10

4. Circuito simbólico de a . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

5. Circuito con interruptores de ejemplo de función booleana . . . . . . . 12

6. Símbolos de las puertas lógicas más comunes . . . . . . . . . . . . . . . 14

7. Arquitectura de Von Neumann con un único bus . . . . . . . . . . . . . 16

8. Estructura matricial de una memoria . . . . . . . . . . . . . . . . . . . 19

9. Diagrama de bloques de la memoria principal . . . . . . . . . . . . . . 20

10. Diagrama de bloques de una UAL, su acumulador, y señales de control 21

11. Control de conexión de un dispositivo a un enlace con puertas triestado 24

12. Esquema de una computadora digital mostrando los enlaces y las señales

de gobierno. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

13. Fases de la ejecución de la instrucción suma. . . . . . . . . . . . . . . . 31

14. Diagrama de bloques de la unidad de control . . . . . . . . . . . . . . . 34

15. Cronograma de la instrucción suma . . . . . . . . . . . . . . . . . . . . 35

16. Esquema del funcionamiento del programa que realiza media de tres

números . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

17. Diagrama de funcionamiento delprograma que calcula si un número es

primo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

18. Diagrama de funcionamiento delprograma que calcula el módulo al cua-

drado de un vector de 4 componentes . . . . . . . . . . . . . . . . . . . 44

19. Diagrama de funcionamiento de programa que escribe una frase en orden

inverso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

20. Diagrama de funcionamiento de programa que almacena una matriz . . 48

21. Diagrama de funcionamiento de programa que lee una matriz y luego

escribe los elementos de su submatriz triangular . . . . . . . . . . . . . 51

22. Diagrama de clases de las clases principales . . . . . . . . . . . . . . . . 56

23. Diagrama de la clase Interface . . . . . . . . . . . . . . . . . . . . . . . 57

24. Diagrama de la clase ProjectsManager . . . . . . . . . . . . . . . . . . 58

25. Diagrama de la clase TabsManager . . . . . . . . . . . . . . . . . . . . 60

26. Diagrama de la clase DebugViewManager . . . . . . . . . . . . . . . . . 62

27. Diagrama de la clase Sobre . . . . . . . . . . . . . . . . . . . . . . . . . 66

7

Page 8: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

28. Diagrama de la clase Emulator . . . . . . . . . . . . . . . . . . . . . . . 66

29. Diagrama de la clase VirtualComputer . . . . . . . . . . . . . . . . . . 69

30. Diagrama de la clase ButtonTabComponent . . . . . . . . . . . . . . . 71

31. Diagrama de la clase XenonHelper . . . . . . . . . . . . . . . . . . . . 72

32. Diagrama de la clase LineCode . . . . . . . . . . . . . . . . . . . . . . 73

33. Diagrama de la clase Instruction . . . . . . . . . . . . . . . . . . . . . . 74

34. Diagrama de la clase PopupListener . . . . . . . . . . . . . . . . . . . . 76

35. Diagrama de la clase Project . . . . . . . . . . . . . . . . . . . . . . . . 77

36. Diagrama de la clase ProjectFile . . . . . . . . . . . . . . . . . . . . . . 77

37. Diagrama de la clase Tab . . . . . . . . . . . . . . . . . . . . . . . . . . 78

38. Diagrama de la clase JConnector . . . . . . . . . . . . . . . . . . . . . 79

39. Diagrama de la clase ConnectorContainer . . . . . . . . . . . . . . . . . 80

40. Diagrama de la clase ConnectLine . . . . . . . . . . . . . . . . . . . . . 81

41. Vista inicial de desarrollo. . . . . . . . . . . . . . . . . . . . . . . . . . 84

42. Ejemplo de desarrollo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

43. Barra de herramientas . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

44. Barra de menús de la vista de desarrollo . . . . . . . . . . . . . . . . . 86

45. Vista de emulación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

46. Barra de herramientas de la vista de emulación . . . . . . . . . . . . . 87

47. Barra de menús de la vista de emulación . . . . . . . . . . . . . . . . . 88

48. Vista de depuración . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

49. Barra de control de de la vista de depuración . . . . . . . . . . . . . . . 89

50. Barra de menús de la vista de depuración . . . . . . . . . . . . . . . . . 90

51. Traducción de texto a instrucciones ensamblador . . . . . . . . . . . . . 93

52. Ejecución de una instrucción . . . . . . . . . . . . . . . . . . . . . . . . 94

53. Cambios de constantes de la Clase Instruction . . . . . . . . . . . . . . 96

54. Cambios en la enumeración OperationCode . . . . . . . . . . . . . . . . 96

55. Cambios en Instruction::updateFromData() . . . . . . . . . . . . . . . . 98

56. Cambios en Instruction::updateFromInstruction() . . . . . . . . . . . . 99

57. Cambios en VirtualComputer::executeNextInstruction() . . . . . . . . . 100

58. Cambios en VirtualComputer::executeNextInstruction() (continuación) 101

59. Cambios en XenonHelper::translateToBinary() . . . . . . . . . . . . . . 101

60. Cambios en XenonHelper::translateFromBinary() . . . . . . . . . . . . 102

8

Page 9: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Índice de cuadros

1. Parte de la tabla ISO 8859-1 . . . . . . . . . . . . . . . . . . . . . . . . 8

2. Algunos códigos de control . . . . . . . . . . . . . . . . . . . . . . . . . 8

3. Tabla de la verdad de la suma de a y b . . . . . . . . . . . . . . . . . . 9

4. Tabla de la verdad del producto de a y b . . . . . . . . . . . . . . . . . 10

5. Tabla de la verdad de a . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

6. Tabla de la verdad de ejemplo de función booleana . . . . . . . . . . . 12

7. Tabla de la verdad de NO . . . . . . . . . . . . . . . . . . . . . . . . . 13

8. Tabla de la verdad de O . . . . . . . . . . . . . . . . . . . . . . . . . . 13

9. Tabla de la verdad de Y . . . . . . . . . . . . . . . . . . . . . . . . . . 13

10. Tabla de la verdad de O negado . . . . . . . . . . . . . . . . . . . . . . 13

11. Tabla de la verdad de Y negado . . . . . . . . . . . . . . . . . . . . . . 14

12. Tabla de la verdad de O . . . . . . . . . . . . . . . . . . . . . . . . . . 14

13. Tabla de transición del biestable RS . . . . . . . . . . . . . . . . . . . . 17

14. Tabla de la verdad de circuito multiplicador . . . . . . . . . . . . . . . 22

15. Ejemplo de instrucción . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

16. Ejemplo de programa en código máquina para el computador . . . . . . 36

17. Las columnas indican el código de operación, modo de direccionamiento,

el código mnemotécnico y una somera explicación para cada una de las

instrucciones de CESIUS. . . . . . . . . . . . . . . . . . . . . . . . . . 38

18. Las columnas indican el código de operación, modo de direccionamiento,

el código mnemotécnico y una somera explicación para cada una de las

instrucciones de CESIUS (Continuación). . . . . . . . . . . . . . . . . . 39

19. Ejemplo de programa. A la izquierda se presenta una lista de las ope-

raciones a efectuar, a la derecha se tiene el programa en la memoria. El

contenido de los registros de la memoria se ha separado en tres bloques

(CO, MD y D) para facilitar el estudio, dicha separación no existe en la

realidad. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

20. Código mnemoténico de programa que realiza media de tres números . 40

21. Código Mnemotécnico de programa que calcula si un número es primo . 42

22. Código Mnemotécnico de programa que calcula el módulo al cuadrado

de un vector de 4 componentes . . . . . . . . . . . . . . . . . . . . . . 43

23. Programa que escribe una frase en orden inverso . . . . . . . . . . . . . 45

24. Programa que almacena una matriz . . . . . . . . . . . . . . . . . . . . 47

9

Page 10: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

25. Programa que lee una matriz y luego escribe los elementos de su subma-

triz triangular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

26. Programa que lee una matriz y luego escribe los elementos de su subma-

triz triangular (continuación) . . . . . . . . . . . . . . . . . . . . . . . 50

10

Page 11: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11

Page 12: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

1. Introducción y objetivos

En este proyecto se desarrolla una implementación emulada por software de una

computadora digital simple. La computadora solo existe a nivel virtual y a nivel teórico,

no existe una implementación tangible o física de dicha computadora. Dicha implemen-

tación virtual cuenta con un entorno de desarrollo, programa de traducción de código

ensamblador a código máquina, depurador y emulador. El esquema de funcionamien-

to de la computadora es simple, y ha sido desarrollado a partir del esquema de Von

Neumann para una computadora de programa almacenado.

El actual proyecto tiene como nombre clave Xenon, y está basado en el programa

antiguamente llamado CESIUS Arahal, Manuel R; Hernández, José Julio; Limón, Daniel

(1986)Acosta Rodriguez, José Ángel (2009). El proyecto consta de varias partes: el

programa desarrollado, su código fuente, y la documentación, siendo este documento la

última parte.

Los objetivos del proyecto son:

Diseño de una computadora simple y desarrollo de un programa software llamado

Xenon que permita emular dicha computadora. Dicho software habrá de incluir

un entorno de programación simple para escribir y compilar programas para el

computador, así como la posibilidad de depurar y ejecutar dichos programas.

Estudio de posibles ampliaciones de este proyecto.

El software Xenon ha de servir para mostrar el funcionamiento de las computado-

ras a personas que estén aprendiendo dicha materia.

El software Xenon ha de poderse ejecutar en diversas plataformas y sistemas

operativos, como pueden ser Windows, Linux, Mac.

La estructura del documento se detalla a continuación:

En el Capítulo 2 se razona el lenguaje de programación escogido para desarrollar

el emulador Xenon.

Explicación teórica del funcionamiento de los computadores digitales en los capítu-

lo 3 y 4, basada en los apuntes de la asignatura de Informática Acosta Rodriguez,

José Ángel (2009).

1

Page 13: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Se realiza una descripción del computador a implementar en el capítulo 5, expli-

cando los elementos del computador y su funcionamiento, el lenguaje de código

máquina, y el lenguaje ensamblador del computador.

El capítulo 6 trata de la estructura del proyecto de software Xenon, incluyendo

una descripción de las clases y métodos que contiene.

El manual de usuario del software Xenon está contenido en el capítulo 7.

El capítulo 8 detalla una descripción de posibles ampliaciones de este proyecto,

como la implementación del software para plataformas móviles como Android, o

ampliar el juego de instrucciones del computador emulado.

Las conclusiones del proyecto y análisis de los objetivos alcanzados se realiza en

el capítulo 9.

Siguen las referencias bibliográ�cas en el capítulo 10 y el código del emulador en

la parte de anexos correspondiente al capítulo 11.

2

Page 14: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

2. Elección del lenguaje de programación a usar

El lenguaje escogido para desarrollar la aplicación ha sido Java. Las principales mo-

tivaciones para usar Java es permite la ejecución de un mismo programa en diversas

plataformas hardware y sistemas operativos, y la velocidad de ejecución es superior a la

de un lenguaje interpretado, acercándose a la velocidad que se consigue con lenguajes

compilados. Los lenguajes de programación compilados son más rápidos que los inter-

pretados porque el código interpretado ha de ser reducido a código máquina en tiempo

real. Java compila el código, pero es compilado en bytecode, para una máquina que

realmente no existe, la Máquina Virtual Java (JVM). El código bytecode a su vez es

interpretado durante la ejecución del programa Java. Así pues la estrategia de Java es

mixta entre código interpretado y compilado. Comúnmente el código bytecode no es

simplemente interpretado, sino que usa compiladores just-in-time que traducen partes

del programa a código máquina de forma que puedan ejecutarse mucho más rápido que

si fueran interpretadas. Por todo esto, un programa Java suele ejecutarse más rápido

que un programa hecho para un lenguaje interpretado. Además, el programa compilado

a bytecode puede ejecutarse sin necesidad de recompilación en cualquier plataforma que

cuente con un intérprete de bytecode, como en los sistemas operativos Windows, Linux

y Mac.

Otras opciones son usar:

C/C++. Como desventaja principal, el ejecutable es dependiente del sistema ope-

rativo. La mayor ventaja radica en que es un lenguaje de más bajo nivel, lo que

permite crear ejecutables más rápidos.

Lenguajes intepretados, como python. Suelen ser multiplataforma, sin embargo

su ejecución, al ser lenguaje interpretado, es más lenta. Además requiere que

el usuario tenga instalado un intérprete, lo cual no siempre ocurre. Una posible

solución a ese problema sería realizar la aplicación web, de modo que sea el servidor

quien ejecute el código. Pero entonces estamos obligando al usuario a disponer

de conexión a internet, y al servidor a ejecutar el código de todos los usuarios, lo

cual puede sobrecargar el servidor.

Otra opción es implementar el emulador en una página web, por ejemplo haciendo

uso de javascript (otro lenguaje interpretado) en la parte del cliente para no

sobrecargar el servidor web.

3

Page 15: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 1: Vista del gestor de versiones del software

A su vez, se ha hecho uso de un sistema de versiones en el desarrollo del software.

El uso de un sistema de versiones permite volver hacia atrás en el tiempo así como

saber exactamente en qué momento se escribió una parte del código o funcionalidad.

Los sistemas de control de versiones son muy útiles cuando el desarrollo de un software

es realizado por un equipo de varias personas, permitiendo añadir cambios locales a

una versión global. En proyectos de cierta envergadura, un sistema de versiones es casi

una necesidad. Este proyecto cuenta con más de 9000 líneas de código, por lo que no

haber hecho uso de un sistema de versiones habría di�cultado el desarrollo del proyecto.

El sistema de versiones usado es Subversion, concretamente el cliente tortoisehg Varios

(2013). En la �gura 1 se puede ver el entorno de dicho cliente subversion.

4

Page 16: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

3. Fundamentos de un computador digital

A continuación se presenta un resumen de los fundamentos de un computador digital.

Para ello en primer lugar se de�ne cómo se puede codi�car en forma binaria cualquier

información. Después se de�nen diferentes codi�caciones de caracteres que se pueden

usar. En el siguiente apartado se describe el álgebra de boole, que permite de�nir

operaciones matemáticas y funciones haciendo uso de información binaria. Finalmente

se realiza una introducción a las puertas lógicas, que implementan funciones que usan

el álgebra de boole mediante circuitos electrónicos.

3.1. Codi�cación binaria de la información

Las computadoras digitales hacen uso de información en forma binaria. La razón

radica en que los dispositivos electrónicos usados en las computadoras hacen uso de

dos niveles de voltaje, correspondientes a los valores binarios 1 y 0. Sin embargo, las

computadoras son capaces de hacer uso de información de muchos tipos, como grá�cos,

textos y sonidos. Dicha información es posible Shannon, Claude E. (1948) representarla

en codi�cación binaria.

3.1.1. Numeraciones binaria y decimal

En el computador que aquí se presenta, solo se hacen uso de números enteros,

no maneja de forma directa números fraccionarios o de punto �otante. El sistema de

numeración de uso más común es aquél en base 10, llamado sistema decimal. En el

sistema decimal, las cifras representan coe�cientes de un polinomio de potencias de 10.

A los coe�cientes di se les denomina dígitos.

D| 10= dn·10n + ...+d1·101+d0·100

Por ejemplo, el número 9482 se descompone en:

9481 |10= 9 · 103 + 4 · 102 + 8 · 101 + 1 · 100

En el sistema binario, la base es 2, y los únicos dígitos posibles son 0 y 1. A los

coe�cientes bi se les denomina bits.

B| 2= bn·2n + ...+b1·21+b0·20

Por ejemplo, el número 11101 en base dos se puede descomponer:

11101 |2= 1 · 24 + 1 · 23 + 1 · 22 + 0 · 21 + 1 · 20 = 29 |10En general, el Teorema Fundamental de la Numeración permite construir números

en un sistema de numeración posicional en una base b cualquiera, siendo b un número

5

Page 17: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

natural.

3.1.2. Codi�cación de números enteros

En un computador digital, la memoria está compuesta por celdas elementales que

corresponden con dígitos binarios, o bits. A su vez, una dirección de memoria en un

computador digital, o un registro, está formado por un grupo de celdas, de forma que

su conjunto permite codi�car números tan grandes como la cantidad de bits del registro

permita, en una representación posicional en base 2.

Por ejemplo, si un registro tiene 16 celdas binarias, es posible almacenar en él nú-

meros entre 0 y 216−1, es decir entre 0 y 65535. En general un computador digital hace

uso de registros de una cantidad de bits determinada, si bien ciertos registros pueden

tener un mayor o menor tamaño.

Si bien la representación binaria de un número entero positivo que acabamos de

explicar es ampliamente usado, existen diferentes opciones de representación de los

números enteros negativos:

Signo-valor absoluto: Una celda, normalmente la correspondiente al dígito más

signi�cativo, es aquella que indica si el número es positivo (con un 0) o negativo

(con un 1). De este modo, el resto de bits del registro, que se re�eren al valor

absoluto del número, son los mismos tanto si el número es negativo como si es

positivo. En este sistema, el número cero tiene dos representaciones.

Complemento a 1: Se reserva el primer bit para el signo. Si el bit es positivo el resto

de números se representa en base dos, si es negativo s realiza el complemento bit a

bit (sustituir ceros por unos, y unos por ceros) del valor absoluto. En este sistema

también existen dos ceros. Por ejemplo, si existen 4 celdas, en complemento a 1:

0|10 = 0000 = 1111

3| 10 = 0011

-3|10= 1100

Complemento a 2: El complemento a dos es igual que el complemento a 1 cuando

el número es positivo. Cuando el número es negativo, es como el complemento a

1 mas la unidad. En este caso solo existe una representación del cero, y tambien

es capaz de representar un número negativo más que las anteriores opciones.

Ejemplos de representación en complemento a dos con 4 celdas son:

6

Page 18: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

0|10 = 0000

4| 10 = 0100

-4|10= 1100

Se puede comprobar que, si el registro tiene n bits, y el número A es negativo, la

representación en complemento a 2 corresponde con A+2n. Por ejemplo:

-4|10= 1100|complemento2≡ −4 + 24 = 12

Los dos primeros sistemas presentan di�cultades para realizar operaciones aritméticas

elementales mediante el uso de circuitos electrónicos, es por ello que se ideó el sistema

de complemento a 2, que es ampliamente usado en los computadores digitales.

3.2. Codi�cación de caracteres

La mayoría de computadoras han de ser capaces de procesar, además de números,

caracteres de texto, como por eemplo:

Letras mayúsculas y minúsculas.

Dígitos.

Signos. Como por ejemplo + - , / ( ) . $% = � ¾ ? [ ] { }

Códigos que no tienen representación grá�ca, pero con funciones de control.

Existen multitud de códigs que permiten almacenar de forma binaria información de

este tipo, entre los que destaca el ASCII (American Standard Code for Information

Interchange), que asigna un número a cada signo. El ASCII necesita 7 bits por carácter,

siendo por tanto capaz de representar 128 signos diferentes. El ASCII extendido es una

versión posterior que hace uso de 8 bits, y es capaz de representar 256 signos.

Concretamente en el computador que se desarrolla en este proyecto, se hace uso del

código ISO 8859-1, que es una norma ISO que de�ne la codi�cación del alfabeto latino

e incluye los diacríticos (como las letras acentuadas, ñ y ç) Esta norma se caracteriza

por coincidir con la codi�cación ASCII en los primeros 128 caracteres, y añadir otros

128 más, haciendo uso de un total de 8 bits.

Se puede observar que las letras son asignadas un número en orden alfabético, y los

dígitos del 0 al 9 son asignados de forma consecutiva, así como que las mayúsculas se

asignan antes que las minúsculas. También cuenta con códigos de control, que no tienen

7

Page 19: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

representación grá�ca y tienen un signi�cado especial. A continuación, en los cuadros

1 y 2 se representan algunos caracteres ISO 8859-1:

Dec Signo

32 espacio33 !47 /48 049 157 9

Dec Signo

65 A66 B67 C68 D69 E90 Z

Dec Signo

97 a98 b99 c100 d101 e122 z

Dec Signo

169 ©225 á233 é237 í243 ó250 ú

Cuadro 1: Parte de la tabla ISO 8859-1

Dec Abreviatura Transmisiones

1 SOH Comienzo de cabecera2 STX Comienzo de texto3 ETX Fin de texto4 EOT Fin de transmisión5 ENQ Petición de transmisión6 ACK Reconocimiento de transmisión7 BEL Señal audible8 BS Retroceso9 HT Tabulación horizontal10 LF Avance de línea11 VT Tabulación vertical13 CR Retorno de carro

Cuadro 2: Algunos códigos de control

3.3. Álgebra de boole

El álgebra de boole es un área del álgebra en que el valor de las variables son los

valores de verdad verdadero y falso, denotados como 0 y 1 comunmente. En álgebra

elemental, los valores de las variables son números y las principales operaciones son la

suma y multiplicación. En cambio, en el álgebra de boole las operaciones principales

son la conjunción (AND) y la disjunción (OR).

George Boole introdujo dicho álgebra en 1854Boole, George (1854). Más tarde, en

1938 Claude ShannonShannon, Claude E. (1937) encontró una aplicación de dicho álge-

bra a los circuitos eléctricos de conmutación. La lógica de boole tiene como aplicaciones

8

Page 20: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

principales en el mundo de la computación el análisis y el diseño de circuitos. El análisis

de circuitos mediante álgebra de boole permite describir el funcionamiento de los mis-

mos. El diseño permite desarrollar implementaciones concretas de funciones de dicho

álgebra.

La potencia del álgebra de boole en el campo de la computación proviene de que

tanto los circuitos digitales como el álgebra de boole hacen uso de información binaria,

donde la unidad elemental solo puede tomar dos valores: verdadero o falso, cero o uno.

3.3.1. De�nición

Formalmente el álgebra de boole está compuesto por variables por y operaciones:

Una variable lógica tomará uno y solo un valor, entre dos opciones posibles. Esas

dos opciones posibles pueden ser cero o uno, o verdadero y falso matemáticamente,

o interruptor abierto e interruptor cerrado en un circuito, o un led encendido o

apagado.

Operaciones binarias. Una operación binaria sobre un conjunto es un cálculo so-

bre dos elementos de dicho conjunto, llamados operandos, y que producen otro

elemento del conjunto. Las operaciones básicas del álgebra de boole son:

� Suma lógica. A+B, también llamado OR. El resultado es 1 si al menos uno de

los operandos vale 1, en otro caso el resultado es cero. El circuito de la �gura

es un ejemplo simbólico de una implementación por medio de interruptores de

esta operación. También se incluye una tabla de la verdad de dicha operación.

En el cuadro 3 se representa la tabla de la verdad de la suma lógica y en la

�gura 2 el circuito simbólico asociado.

a/b 0 1

0 0 11 1 1

Cuadro 3: Tabla de la verdad de la suma de a y b

� Producto lógico. A·B, también llamado AND. El resultado es 1 si y solo

si ambos operadores valen 1, en otro caso el resultado es cero. El circuito

9

Page 21: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 2: Circuito de la suma de a y b

de la �gura es un ejemplo simbólico de una implementación por medio de

interruptores de esta operación.También se incluye una tabla de la verdad

de dicha operación. En el cuadro 4 se representa la tabla de la verdad del

producto lógico y en la �gura 3 el circuito simbólico asociado.

a/b 0 1

0 0 01 0 1

Cuadro 4: Tabla de la verdad del producto de a y b

Figura 3: Circuito simbólico del producto de a y b

� Negación lógica. a, también llamado NOT. El resultado es 1 si el operador

es 0, el resultado es 0 si el operador es 1. El circuito de la �gura es un

ejemplo simbólico de una implementación por medio de interruptores de esta

operación.También se incluye una tabla de la verdad de dicha operación. En

el cuadro 5 se representa la tabla de la verdad de la negación lógica y en la

�gura 4 el circuito simbólico asociado.

10

Page 22: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

a a

0 11 0

Cuadro 5: Tabla de la verdad de a

Figura 4: Circuito simbólico de a

3.3.2. Propiedades del álgebra de boole

Las operaciones de�nidas tienen las siguientes propiedades:

Elementos neutros: Para la suma el cero es elemento neutro, es decir a+0 = a.

Para el producto el 1 es el elemento neutro pues a·1 = a.

Conmutatividad: Para la suma, se cumple que a + b = b + a. Para el producto

se cumple que a·b = b·a.

Asociatividad: Los paréntesis indican el orden en que se realizan una serie de

operaciones. La asociatividad implica que (a + b) + c = a + (b + c) para la

suma, y que (a·b)·c = a·(b·c) para el producto.

Distributividad: Es una propiedad que implica dos reglas válidas para reemplazar

una operación por otra. Implica que (a + b)·c = a · c + b · c y que a + (b · c) =

(a+ b) · (a+ c).

Leyes de Morgan, esta propiedad hace uso de las tres operaciones elementales del

álgebra de boole. Implica que a+ b = a · b y a · b = a+ b.

3.3.3. Funciones booleanas

Una función es una expresión que contiene varias operaciones booleanas sobre un

conjunto de variables. Existirá un valor unívoco de la función dados unos valores con-

cretos para las variables de la función. Existen varias formas de de�nir la función, una

forma es mediante el uso de operaciones sobre dichas variables, otra forma es mediante

una tabla de la verdad que explicite el valor de la función para todas y cada una de las

11

Page 23: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

combinaciones de valores posibles de las variables de la función. Otra forma es mediante

un circuito con interruptores controlados por las variables de la función. Por ejemplo

una función f(a, b, c) se puede expresar de las siguientes formas:

f : (a, b, c) 7→ L = f(a, b, c) = a · b · c

a b c L0 0 0 00 0 1 00 1 0 00 1 1 01 0 0 01 0 1 01 1 0 01 1 1 1

Cuadro 6: Tabla de la verdad de ejemplo de función booleana

Figura 5: Circuito con interruptores de ejemplo de función booleana

3.3.4. Puertas lógicas

La equivalencia elemental entre elementos del álgebra de boole con los dispositivos

electrónicos de un computador digital está en las puertas lógicas, que son capaces de

realizar operaciones y funciones booleanas. Dichas puertas lógicas no contienen partes

móviles, sino que manejan el paso de señales mediante el uso de elementos electrónicos

como diodos y transistores, entre otros. En la �gura 6 se representan los símbolos de

diferentes puertas lógicas. Las puertas lógicas elementales son:

NOT. También llamado puerta NO. La tabla de la verdad se puede ver en el

Cuadro 7.

OR. Llamada suma lógica o puerta O. La tabla de la verdad se puede ver en el

Cuadro 8.

12

Page 24: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

a a

0 11 0

Cuadro 7: Tabla de la verdad de NO

a b a+b

0 0 00 1 11 0 11 1 1

Cuadro 8: Tabla de la verdad de O

AND. Producto lógico o puerta Y. La tabla de la verdad se puede ver en el Cuadro

9.

a b a·b0 0 00 1 01 0 01 1 1

Cuadro 9: Tabla de la verdad de Y

NOR. También llamado O negado. La tabla de la verdad se puede ver en el Cuadro

10.

a b a+ b

0 0 10 1 01 0 01 1 0

Cuadro 10: Tabla de la verdad de O negado

NAND. Llamado Y negado. La tabla de la verdad se puede ver en el Cuadro 11.

13

Page 25: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

a b a · b0 0 10 1 11 0 11 1 0

Cuadro 11: Tabla de la verdad de Y negado

XOR. Suma lógica exclusiva o puerta O exclusivo. La tabla de la verdad se puede

ver en el Cuadro 12.

a b a⊕b0 0 00 1 11 0 11 1 0

Cuadro 12: Tabla de la verdad de O

Figura 6: Símbolos de las puertas lógicas más comunes

14

Page 26: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

4. Estructura general de un computador digital

En este capítulo se describe la estructura de un computador digital sencillo. Para

ello primero se introduce la arquitectura de Von Neumann, que es la arquitectura que

usa el computador digital en que se enmarca este proyecto. A continuación se describen

los principios básicos del almacenamiento de datos en una computadora digital.Después,

se introduce el funcionamiento de diferentes elementos que componen un computador

con la arquitectura de Von Neumann:

La unidad de memoria central, que es la unidad principal de almacenamiento del

computador.

La unidad aritmético-lógica, que permite realizar operaciones matemáticas con

datos.

La unidad de entrada y salida se encarga de comunicar al computador con el

exterior, ya sea con otras computadoras o periféricos.

Los enlaces y buses, cuya función es conectar todos los demás elementos del

computador.

La unidad de control, cuya tarea es coordinar y hacer uso de los demás elementos

del computador para ejecutar cada instrucción correctamente.

4.1. Arquitectura de Von Neumann

La computadora digital que en este proyecto se desarrolla tiene una arquitectura de

Von Neuman. El modelo de Von Neumann, o la arquitectura de Princeton deriva de la

descripción de una arquitectura de computador digital realizada por el cientí�co John

von Neumann en 1945 von Neumann, John (1945). En dicha arquitectura existe una

unidad de proceso consistente en una unidad aritmético-lógica, una serie de registros del

procesador, una unidad de control que contiene un registro de instrucción y un contador

de programa, una memoria para guardar instrucciones, un sistema de almacenamiento

externo masivo y mecanismos de entrada y salida de datos.

La arquitectura describe un computador de programa almacenado donde la bús-

queda de instrucciones y el desarrollo de operaciones sobre datos no pueden ocurrir de

forma simultánea porque comparten un bus común. Esta limitación se conoce como el

cuello de botella de Von Neumann y a menudo limita el rendimiento del sistema. Otras

15

Page 27: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

arquitecturas, como la llamada arquitectura de Harvard, no presentan dicho cuello de

botella, pues presentan caminos diferentes para el almacenamiento y encaminamiento

de señales de instrucciones y de datos.

En general, un computador de programa almacenado mantiene sus instrucciones

programadas y sus datos en memoria de acceso aleatorio con capacidad de escritura y

lectura. La mayoría de los computadores modernos almacenan los datos y las instruc-

ciones en una misma memoria. La �gura 7 muestra un esquema de la arquitectura de

Von Neumann con un único bus.

Figura 7: Arquitectura de Von Neumann con un único bus

4.2. Almacenamiento de la información

Un computador necesitará guardar en algún dispositivo la información si quiere

poder procesarla. Como antes hemos dicho, la unidad fundamental de información de

un computador digital es el bit, o dígito binario. El dispositivo físico elemental que es

capaz de almacenar un bit se denomina celda o célula elemental.

Existen diversos tipos de dispositivos físicos capaces de almacenar un bit. Entre ellos

se encuentran los biestables. Los biestables suelen realizarse mediante circuitos electró-

nicos basados en las puertas lógicas que ya hemos analizado, pero la principal diferencia

radica en que los biestables tienen memoria. Es decir, las salidas de un biestable no solo

dependen de las entradas, sino del estado en que se encuentra, es decir dependen del

valor de sus entradas anteriores. Este tipo de circuitos se llaman circuitos secuenciales.

Entre los diversos tipos de biestables se encuentra el biestable RS. Se puede de�nir

para el biestable RS una tabla de transición, que da la salida y(t1) en el instante t1a

16

Page 28: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

partir de las entradas RS y la salida y(t0) en el instante anterior t0. El cuadro 13 muestra

la tabla de transición del biestable RS.

RS→ 00 01 10 11

y(t0)=0 0 1 0 Xy(t0)=1 1 1 0 X

Cuadro 13: Tabla de transición del biestable RS

El valor X para la columna RS=11 indica que el biestable no ha de usarse con esas

entradas. La entrada S signi�ca set y como se puede observar en la table, pone a 1 el

biestable. La entrada R signi�ca reset y pone a cero el biestable. Si ambas entradas

están a cero, la salida del biestable será conservada.

Si bien las celdas son las unidades elementales de memoria, para representar números

mayores a 1 o 0 es necesario hacer uso de conjuntos de celdas, que componen un registro.

Como ya se ha mencionado, un registro corresponde con una representación posicional

en base 2 de un número. Por ejemplo un registro de 11 células será capaz de representar

211 =2048 números diferentes.

Al equiparar un conjunto de biestables con el concepto de registro, es a menudo

necesario que cuando dicho registro es actualizado todas las celdas se actualicen de

forma coordinada, de forma que añadimos a los biestables una entrada de sincronismo.

En el contexto de la memoria principal de un computador digital, se de�nen dife-

rentes unidades de memoria, de entre las cuales ya hemos visto varias:

Bit: Unidad elemental de información binaria y que se almacena en una celda

elemental

Byte u octeto: Formada por 8 bits, y necesita por tanto de 8 celdas de memoria.

Palabra: La información almacenada en un registro de un computador se denomi-

na palabra. Un registro puede tener cualquier número de celdas, si bien los más

usuales son de 16, 32, y 64 bits o 2, 4, y 8 bytes.

En la arquitectura de Von Neumann la memoria permite tanto almacenar datos como

instrucciones y se de�nen 3 operaciones de memoria:

Direccionamiento: Selecciona la información de un sector de memoria a partir de

la posición (dirección) de ese sector en la memoria.

17

Page 29: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Lectura: Lleva a cabo una copia de la información que existen en un sector de la

memoria a otro bloque del computador, como un registro o un bus. En general

la lectura es no destructiva, de forma que tras la lectura del dato, el mismo sigue

almacenado en memoria.

Escritura: Almacena información en un sector de memoria. Es una operación

destructiva de forma que el dato que había almacenado previamente en memoria

es destruido y reemplazado por un nuevo dato.

Existen multitud de tipos de memorias, y multitud de clasi�caciones, entre otras:

Tiempo de acceso: Según el tiempo que transcurre desde que se ordena la opera-

ción de memoria hasta que ésta termina.

Capacidad: Se re�ere a la cantidad de información que es capaz de almacenar la

memoria. Se suele hacer uso de los pre�jos kilo- y mega-, entre otros.

Modo de acceso: De�ne las formas en que se accede a la información, por ejemplo:

� Acceso directo: para acceder al dato basta con acceder a una posición de

memoria conocida. El tiempo de acceso en este caso es independiente de

dónde se encuentra el dato.

� Acceso indirecto: Para acceder al dato es necesario acceder a una posición de

memoria que nos indicará en qué posición de memoria se encuentra el dato.

� Acceso secuencial: Para acceder al dato hemos de leer o dejar pasar la infor-

mación que le precede.

Volatilidad: Indica si la información almacenada puede ser modi�cada o destruida

cuando no se suministra energía a la memoria. Las memorias de semiconductores

suele ser volátil, y la de discos y cintas suele ser no volátil.

Papel de la memoria en el computador:

� Memoria principal: En ella se almacena el programa que se está ejecutando,

en general es volátil y de acceso directo y está implementada con circuitos

de semiconductores.

18

Page 30: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

� Memoria auxiliar: Suele ser mucho más masiva, no volátil y suele tener un

mayor tiempo de acceso. Estos dispositivos se consideran periféricos y por

ello es necesario una unidad de adaptación llamada de entrada y salida para

conectarla con el computador.

Figura 8: Estructura matricial de una memoria

La memoria principal suele implementarse con una serie de registros, todos del

mismo tamaño, en una disposición matricial. Recordemos que el ancho del registro

es también la longitud de una palabra en el computador. En la disposición matricial,

cada columna representa un bit de cada registro, y el número de �las es el número

de registros. El número de �las suele ser mucho mayor al de columnas, y suele ser un

múltiplo de base 2. A su vez cada �la, es decir, cada registro, corresponde con una única

dirección de memoria, de forma que para realizar una operación de lectura o escritura

sobre ese registro basta con conocer la dirección de dicho registro. Si, por ejemplo, una

memoria tiene 210registros de 16 bit cada uno, la capacidad de la memoria, en bits es

de 16·210 = 16384 bits. La �gura 8 muestra la estructura matricial de una memoria.

La selección de una dirección de memoria es un paso que hay que realizar antes de la

lectura/escritura de dicho registro. El elemento de la memoria que se encarga de realizar

la selección es el decodi�cador de direcciones. Si por ejemplo existen 210direcciones de

memoria, para seleccionar una dirección concreta habrá que pasar una dirección de 10

bits al decodi�cador de direcciones.

4.3. Unidad de memoria central

La unidad de memoria central contiene tanto las instrucciones del programa a eje-

cutar como los datos almacenados por el usuario. La �gura 9 presenta el diagrama de

bloques de la memoria principal. Los bloques de la unidad de memoria central son:

19

Page 31: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

S. Es el registro que se encarga de seleccionar una dirección de memoria. Si existen

2mdirecciones de memoria, el registro S tendrá un tamaño de m bits.

LECM, ESCM. Señales de control, LECM de lectura, y ESCM de escritura.

T. Registro de almacenamiento temporal. En caso de realizar una lectura de la

memoria, el dato leído será almacenado en este registro. En caso de escritura en

memoria, será el dato de este registro el que será escrito en memoria. El tamaño

de este registro coincide con el tamaño de los registros de la memoria.

Figura 9: Diagrama de bloques de la memoria principal

Es decir, para realizar una operación de lectura:

En primer lugar es necesario seleccionar la posición de memoria que vamos a leer.

Para ello introducimos la dirección de memoria en el registro S.

Después activamos la señal LECM, de forma que el dato de la dirección seleccio-

nada es copiado al registro T.

Finalmente copiamos el contenido del registro T al lugar de destino (un bus u

otro registro).

Los pasos para una operación de escritura son parecidos:

En primer lugar es necesario seleccionar la posición de memoria en la que vamos

a escribir. Para ello introducimos la dirección de memoria en el registro S.

Copiamos el dato que queremos escribir en el registro T.

20

Page 32: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Finalmente copiamos el contenido de T en la posición adecuada en la memoria,

activando la señal de control ESCM.

4.4. Unidad aritmético-lógica

Un elemento muy importante del computador digital es la unidad aritmético lógica.

Esta unidad es capaz de realizar operaciones aritméticas y lógicas sobre una o varias

señales de entrada. Para ello hace uso de circuitos electrónicos con puertas lógicas y del

álgebra de boole. Algunas operaciones aritméticas comunes de una UAL son la suma,

resta, multiplicación o división. Ejemplo de operaciones lógicas son comparaciones de

igualdad. La �gura 10 representa el diagrama de bloques de una UAL.

Figura 10: Diagrama de bloques de una UAL, su acumulador, y señales de control

De forma frecuente, el resultado de las operaciones de la UAL se guarda en un

registro Acumulador, el cual a su vez se retroalimenta como operando de la UAL. De

este modo, por ejemplo, para realizar una suma:

Primero se lleva el primer operando a la UAL, y con la señal de control CARGA

el operando pasa al acumulador.

Después se lleva el segundo operando a la entrada de la UAL.

Como el primer operando está en el Acumulador y éste está retroalimentado a la

UAL, en este momento los dos operandos están como sendas entradas de la UAL,

por lo que ahora se activa la señal de control SUMA, realizando de forma efectiva

la suma.

21

Page 33: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Finalmente el resultado, que está en el acumulador, se puede transferir a otros

elemenos del computador.

Puesto que el resultado de la UAL solo depende de las señales de control y operandos

de entrada en un momento dado, para crear una UAL simple basta con hacer uso de

circuitos combinacionales. Por ejemplo, un circuito multiplicador de números de dos

bits tiene la tabla de la verdad del cuadro 14, que habrá que implementar con puertas

lógicas:

a1 a0 b1 b0 m3 m2 m1 m0

0 0 0 0 0 0 0 00 0 0 1 0 0 0 00 0 1 0 0 0 0 00 0 1 1 0 0 0 00 1 0 0 0 0 0 00 1 0 1 0 0 0 10 1 1 0 0 0 1 00 1 1 1 0 0 1 11 0 0 0 0 0 0 01 0 0 1 0 0 1 01 0 1 0 0 1 0 01 0 1 1 0 1 1 01 1 0 0 0 0 0 01 1 0 1 0 0 1 11 1 1 0 0 1 1 01 1 1 1 1 0 0 1

Cuadro 14: Tabla de la verdad de circuito multiplicador

4.5. Unidad de entrada y salida

Las computadoras interaccionan con el exterior por medio de los periféricos. Esta

interacción con el exterior es necesaria para que una computadora resulte de alguna

utilidad. Los periféricos más comunes son el teclado y la pantalla.

Una característica típica de los periféricos es la diferente velocidad o tasa de trans-

misión de datos entre diferentes periféricos. El computador ha de ser capaz de tratar

con periféricos que se comunican con éste a muy diversas velocidades. Por ejemplo,

una pantalla puede necesitar recibir varios megabits de datos por segundo y un te-

clado normalmente no va a enviar más de 20 caracteres por segundo. Por lo general,

22

Page 34: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

son los propios periféricos los que cuentan con los adaptadores necesarios para poderse

comunicar con el computador de forma adecuada.

El computador digital que aquí se desarrolla cuenta solo con dos periféricos: un

teclado y una pantalla. Otros periféricos comunes para computadoras digitales son el

ratón, la impresora y dispositivos de almacenamiento masivo.

Teclado de computador. Es un dispositivo con botones o teclas dispuestas de forma

similar a en una máquina de escribir, que actúan como conmutadores electrónicos.

La pulsación de dichas teclas, ya sea de forma individual o de forma combinada,

es detectada por el teclado y manda al computador señales codi�cadas de carac-

teres de texto, números y señales de control. Dicha información es leída de forma

periódica por el computador. La velocidad de transmisión de los teclados suele

ser baja (del orden de 10 caracteres por segundo).

Monitor de visualización. Es una pantalla electrónica de visualización de datos.

Cuando un programa quiere que el usuario reciba datos, éstos son mandados al

monitor o pantalla. Existen multitud de tipos de pantallas, como por ejemplo las

pantallas de tubos de rayos catódicos y las pantallas planas LCD. A su vez las

pantallas pueden comunicarse a más o menos velocidad con el computador, si bien

por lo general la velocidad de transmisión requerida por una pantalla es superior

a la requerida por un teclado. El uso de un monitor requiere de un dispositivo

llamado tarjeta de vídeo que funcione como intermediario y adaptador entre ésta

y el computador. La resolución de la pantalla, la cantidad de colores disponibles,

así como el ratio de refresco de la misma, son factores que imponen requerimientos

mínimos en la cantidad de memoria y potencia de cálculo necesarias para que un

computador pueda hacer uso de una pantalla.

4.6. Enlaces o buses

Los enlaces, o buses en inglés, cumplen el objetivo de conectar los diferentes elemen-

tos del computador. La forma más básica de conectar una serie de dispositivos es conec-

tarlos todos con todos, pero si tenemos n dispositivos eso signi�ca tener n(n−1)2

conexiones

bidireccionales, con lo que el número de conexiones necesarias para un número no muy

grande de dispositivos es poco factible.

En un bus de datos, varios dispositivos se conectan a un mismo bus, y en un momento

dado solo existirá una fuente de datos, pudiendo recibir esos datos todos los demás

23

Page 35: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

dispositivos. Es decir, un dispositivo hablará y los demás estarán a la escucha. Los

enlaces entre dispositivos mediante un mismo bus tienen diversas ventajas, entre ellas:

Número reducido de conexiones necesarias.

Simpli�cación del sistema, de forma que cada dispositivo solo necesita una entrada

y una salida.

Facilidad para la expansión, es decir, facilidad para añadir mas dispositivos.

Facilidad de implementación en circuitos electrónicos.

Posibilidad de que los dispositivos se encuentren a distancias grandes unos de

otros.

Figura 11: Control de conexión de un dispositivo a un enlace con puertas triestado

A su vez los buses tienen algunos inconvenientes, como un mayor tiempo de trans-

misión, ya que varios dispositivos que quieran transmitir a la vez no podrán hacerlo,

alguno tendrá que esperar. Para evitar colisiones de mensajes, existen protocolos que

por ejemplo delimitan los momentos en que los dispositivos pueden comenzar a hablar.

En general, por cada dispositivo existirá una señal de gobierno que marcará si el

dispositivo accede al bus (ya sea para leer o para escribir en él). La señal de gobierno

se suele conectar a puertas triestado, de forma que cuando la señal de gobierno es cero,

la salida �uctúa libremente tomando el valor que otro dispositivo le impone, y cuando

es uno, la puerta transmite la información a la salida. La �gura 11 representa el control

de conexión de un dispositivo a un enlace con puertas triestado.

4.7. Unidad de control

La unidad de control se encarga de interpretar las instrucciones a ejecutar, y mandar

las señales de control necesarias a los elementos correspondientes del computador, en el

24

Page 36: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

tiempo y orden adecuados según la instrucción. Es decir, la ejecución de una instrucción

se realiza activando señales de gobierno, a las que se denomina microórdenes. Estas

microórdenes se ejecutan todas dentro de un solo ciclo de reloj (el tiempo de ejecución

de una instrucción, por lo general).

Se denomina cronograma de operaciones de una instrucción a la representación

temporal de la evolución de las distintas señales de gobierno y control activadas en

dicha instrucción. Cada arquitectura de computador tiene cronogramas diferentes para

cada instrucción, pues dichos cronogramas dependen de la arquitectura especí�ca del

computador. En la próxima sección se desarrollará la unidad de control especí�ca del

computador que describe este documento.

Un tipo de unidades de control es el llamado unidad de control cableada. Esta unidad

se implementa con una serie de circuitos lógicos y biestables que activa y desactiva las

señales de control y gobierno en el momento adecuado en cada tipo de instrucción.

Como cada instrucción necesita de un cronograma diferente, el circuito de las unidades

de control cableadas suele ser complejo, sobre todo cuantas más instrucciones diferentes

implemente el computador. Otro tipo de unidades de control son las unidades de control

microprogramadas, que hacen uso de una micro-memoria, eliminando la complejidad

del sistema.

25

Page 37: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

26

Page 38: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

5. Descripción de la máquina a implementar

Este capítulo describe el computador que el software Xenon ha de implementar. En

la primera sección se enumeran los elementos de dicho computador, incluyento entre

otros los registros y las señales de control. Sigue un apartado que explica cómo procede

la ejecución de una instrucción del computador. A continuación se describe el código

máquina del computador, que es el código binario que maneja el computador. Después

se detalla el código ensamblador, que es un lenguaje simbólico más sencillo de usar por

una persona que el código máquina. El capítulo termina con una serie de ejemplos de

programas escritos en lenguaje ensamblador.

5.1. Elementos del computador

Figura 12: Esquema de una computadora digital mostrando los enlaces y las señales degobierno.

El computador implementa una arquitectura basada en la de Von Neumann, donde

los periféricos de la unidad de entrada y salida son la pantalla y el teclado. Los elementos

con que cuenta el computador y que aparecen en la �gura 12 son:

1. Un enlace M que une la memoria, la unidad de control y la UAL. La información

que se o transmite puede ser de diversas clases: datos y resultados de operaciones,

instrucciones del programa y direcciones de memoria.

2. Otro enlace S que une la unidad de control y el selector de posiciones de memoria.

Por �él se transmiten direcciones de memoria.

3. La memoria principal, con organizaci�ón matricial.

27

Page 39: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

4. La UAL con registro acumulador que almacena uno de los operandos y el resultado

de las operaciones.

5. Los siguientes registros:

A. Registro acumulador de la UAL.

S. Registro de selección de memoria.

T. Registro tampón de comunicación entre la memoria y la línea M.

P. Contador de pasos de programa. Indica la posición dentro de la memoria

de la o instrucción a ejecutar.

I. Registro de instrucción. Guarda en cada momento la instrucci�ón que se

ejecuta en o o ese paso.

E. Registro de comunicación con el exterior. Permite tomar datos del teclado

o llevarlos o a la pantalla. Es una forma simple e idealizada de la unidad de

control que se ha descrito anteriormente.

6. Las señales del computador:

EA. Señal de escritura en el registro A. Guardará en A el resultado de la

ALU. Si además de EA, la señal EO está activada pero las señales SUMA,

RESA, MULTA, DIVA y MODA no están activadas, la ALU leerá el bus M

y será el dato del bus M el que se guarde en el registro A.

SA. Permite escribir el dato del registro A en el bus M.

EO. Asigna el dato del bus M a la entrada de la ALU.

SUMA. Realiza la operación suma A+M en la ALU de los datos de A y del

bus M (si la señal EO está activada).

RESA. Realiza la operación resta A−M en la ALU de los datos de A y del

bus M (si la señal EO está activada).

MULTA. Realiza la operación multiplicación A·M en la ALU de los datos de

A y del bus M (si la señal EO está activada).

DIVA. Realiza la operación división A/M en la ALU de los datos de A y del

bus M (si la señal EO está activada).

28

Page 40: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

MODA. Realiza la operación división Amod M en la ALU de los datos de A

y del bus M (si la señal EO está activada).

INCP. Incrementa P en una unidad.

EP. Asigna al registro P el valor del bus S.

SP. Escribe el valor del registro P en el bus S.

ES. Escribe el valor del bus S en el registro S, seleccionando dicha posición

de memoria.

SD. Escribe el valor del registro D (los 11 bits menos signi�cativos del registro

I) en el bus S.

EI. Escribe el valor del bus M en el registro I.

LECM. Lee la posición de memoria seleccionada por el registro S y la escribe

en el registro T.

ESCM. Escribe el valor del registro T en la posición de memoria seleccionada

por el registro S.

ET. Escribe el valor del bus M en el registro T.

ST. Escribe el valor del registro T en el bus M.

EE. Escribe el valor del bus M en el registro E.

SE. Escribe el valor del registro E en el bus M.

LEET. Lee el valor de los datos de entrada del teclado y lo escribe en el

registro E.

ESCP. Muestra en la consola el valor del registro E.

5.2. Funcionamiento del computador

Como ya se ha mencionado con anterioridad, el computador que aquí se presenta es

una máquina de programa almacenado, de modo que en la memoria se almacenan tanto

datos como instrucciones.El computador cuenta con la mayoría de los dispositivos ya

mencionados, conectados a través de enlaces de tipo bus, permitiendo la transferencia

de información de un dispositivo a otro. La unidad de control es el elemento que envía

órdenes a todos los demás.

El programa se encuentra almacenado en memoria, con las instrucciones situadas

de forma secuencial. La unidad de control se encargará de ir leyendo y ejecutando las

29

Page 41: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

instrucciones del programa en el orden adecuado. La unidad de control cuenta con un

registro P que guarda la posición de memoria de la instrucción que se ejecuta. En general

el valor del registro P se incrementa en una unidad tras ejecutar cada instrucción, si

bien existen como excepciones las instrucciones de salto.

El registro P sirve para localizar la instrucción a ejecutar. Después de ser localizada

en memoria, dicha instrucción se copia al registro I. Entonces la unidad de control

interpreta la instrucción y activa las señales de gobierno que correspondan con dicha

instrucción en el orden adecuado.

Una instrucción, que al �n y al cabo es un número que es guardado en el computador

en binario, se puede dividir en tres partes:

Código de operación (CO): Indica la operación a realizar. En este computador

consta de 4 bits, de modo que existen hasta 16 operaciones diferentes.

Modo de direccionamiento (MD): El computador trabajará con modos de direc-

cionamiento directo e indirecto. Como solo trabajaremos con esos dos posibles

modos de direccionamiento, usaremos 1 bit para indicar el modo. En el modo

directo el operando es la dirección del dato, o de la posición de memoria donde

se guardará el resultado de la operación.

Dirección de memoria u operando: Esta dirección tendrá diferentes signi�cados

dependiendo del código de operación y del modo de direccionamiento. Por ejemplo,

en la suma directa indica la dirección de memoria donde se encuentra el dato a

sumar. La dirección de memoria consta de 11 bits.

En total una instrucción está formada por 16 bits, que a su vez es la longitud de

cada registro en la memoria principal. A su vez, las direcciones de memoria tienen una

longitud de 11 bits, lo cual permite direccionar 211 =2024 direcciones de memoria, de

forma que la memoria principal tiene una capacidad total de 16·2048 = 32738 bits = 4

kilobytes.

Como ejemplo, podemos analizar la instrucción del cuadro 15:

CO MD D0101 0 000 0000 1000

Cuadro 15: Ejemplo de instrucción

El código de operación 0101 indica en este caso sumar al acumulador el contenido

de una dirección de memoria. El modo de direccionamiento 0 es directo, de forma que

30

Page 42: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

el el dato a sumar se encuentra en la dirección 000 0000 1000, que corresponde en base

2 con la dirección 8.

5.2.1. Ejecución de instrucciones

La ejecución de cada instrucción se divide en 4 fases. Las fases corresponden con

acciones diferentes en cada instrucción. Estas fases se representan en la �gura 13 para

el caso sencillo de una suma.

Figura 13: Fases de la ejecución de la instrucción suma.

Búsqueda de la instrucción. En la �gura P indica que la instrucción está en la

dirección de memoria 17. Se direcciona dicha posición de memoria copiado P al

registro S. Luego realiza una lectura y se copia el contenido de la memoria en esa

posición al registro I, que pasa a contener la dirección a ejecutar.

Búsqueda del operando. En este caso el operando está en la posición de memoria

8, luego el computador direcciona dicha posición copiando 8 al registro S.

Ejecución de la instrucción. El contenido de memoria en dicha posición es leído

y se traslada al registro de operando de la UAL. Entonces se realiza la suma del

acumulador con el operando, y dicha suma se guarda en el registro acumulador.

Preparación de la siguiente instrucción. Se incrementa en una unidad el registro

P, que pasará a contener la posición de memoria de la siguiente instrucción.

31

Page 43: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

La ejecución de una instrucción es dirigida por la unidad de control mediante cambios

en las señales de gobierno, que permiten realizar tanto operaciones como transferencias

entre registros. Una descripción más formal de la ejecución de una instrucción es aquella

en que se detallan las transferencias entre los registros, a la vez que las operaciones arit-

méticas y de lectura y escritura en memoria. Por ejemplo, la ejecución de la instrucción

descrita anteriormente se puede describir de la siguiente forma:

Búsqueda de la instrucción. Se lee de memoria la instrucción a ejecutar, que está

en la dirección que indica el registro P. Las operaciones elementales a realizar son:

� Direccionamiento: Transferir a S el contenido de P, se simboliza mediante

(P)→S.

� Lectura de memoria: Se trans�ere al registro T el dato guardado en la posi-

ción de memoria direccionada: M(S)→T

� Transferencia del registro T al registro I, que es el registro que la unidad de

control interpreta como instrucción: T→I

Búsqueda del operando: En la instrucción de este ejemplo, el código de operación

corresponde a una suma, y el direccionamiento es directo, de forma que el operador

está en la posición de memoria que indica D. Para leer el operando:

� Direccionamiento de D: (D)→S.

� Lectura de memoria: M(S)→T. Lee la posición de memoria direccionada,

copiándola al registro T.

Ejecución de la instrucción. Se realiza la operación de suma y ésta se guarda en

el registro acumulador. Es decir, (T)+(A)→A.

Preparación de la siguiente instrucción. En el caso de la suma, la siguiente ins-

trucción viene dada por P+1, de modo que P+1→P.

Este método de representación de operaciones consiste en detallas las transferencias

elementales entre registros. Es importante recalcar que dichas transferencias y opera-

ciones son llevadas a cabo por la unidad de control mediante la activación coordinada,

por parte de dicha unidad de control, de las diversas señales de gobierno que posee el

computador. Por ejemplo, para escribir en el registro T será necesario activar ET y para

leer T habrá que activar ST.

32

Page 44: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

5.2.2. Instruciones de salto

En multitud de instrucciones, tras su ejecución el registro P contador de pasos se

incrementa en la unidad. Existe otro tipo de instrucciones que realizan saltos entre

instrucciones, de una posición de memoria a otra. Por ejemplo, la instrucción de salto

incondicional carga en P la dirección del operando de dicha instrucción, de forma que

tras esta instrucción será la instrucción situada en esa posición la que se ejecutará. De

este modo, los pasos de ejecución de la instrucción salto incondicional son:

Búsqueda de la instrucción. Se lee la instrucción que se va a ejecutar a partir del

conocimiento de su posición en la memoria, dato contenido en el registro P.

� Direccionamiento: Transferir a S el contenido de P, se simboliza mediante

(P)→S.

� Lectura de memoria: Se trans�ere al registro T el dato guardado en la posi-

ción de memoria direccionada: M(S)→T

� Transferencia del registro T al registro I, que es el registro que la unidad de

control interpreta como instrucción: T→I

Búsqueda del operando. El operando de la instrucción es directamente D, de forma

que no hace falta acceder a la memoria principal para acceder al operando.

Ejecución de la instrucción. En este caso solo es necesario transferir el contenido

de D al registro P. (D)→P

Preparación de la siguiente instrucción. Normalmente esto signi�caría modi�car

el registro P, pero en el caso de las instrucciones de salto esto ya se realiza en la

fase de ejecución de la instrucción, así que en esta fase no hacemos nada.

Si bien la instrucción de salto incondicional es la más sencilla dentro de las instrucciones

de salto, existen instrucciones de salto llamadas condicionales, de forma que el resultado

de la ejecución de la instrucción, esto es el contenido del registro P, será uno u otro

dependiendo de si se cumple cierta condición. Esta condición puede ser por ejemplo

una comparación. Este tipo de instrucciones es importante a la hora de realizar lo que

se denominan bifurcaciones en un programa.

33

Page 45: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

5.2.3. Funcionamiento de la unidad de control

La unidad de control de interpretar las instrucciones a ejecutar y activar las señales

de gobierno o control adecuadas para asegurar su ejecución. Como ya se ha mencionado

la ejecución de cada instrucción se divide en una serie de etapas, en las cuales se activa-

rán unas señales de gobierno u otras dependiendo de la instrucción que se esté tratando

(concretamente dependiendo del código de operación y modo de direccionamiento). La

activación de las señales de gobierno en el transcurso de la ejecución de la instrucción

se denomina microórdenes. La �gura 14 muestra un diagrama de la unidad de control.

Las microórdenes tienen como objetivo realizar transferencias entre registros, así

como realizar operaciones sobre el contenido de los mismos. La complejidad de un

cronograma depende de factores como la cantidad de registros del computador, la com-

plejidad de la UAL o la diversidad de instrucciones que implementa el computador. El

diseñador de la computadora tendrá que encargarse de realizar el cronograma de cada

instrucción, y a partir de él crear un diseño de circuitos combinacionales y secuenciales

que implemente físicamente la unidad de control.

El circuito de la unidad de control suele ser complejo y como ya se ha mencionado

con anterioridad existe otra opción para su realización, ideada por Wilkes, que trata de

evitar dicha complejidad haciendo uso de una memoria especial donde se guarden las

microórdenes.

Figura 14: Diagrama de bloques de la unidad de control

Para visualizar el trabajo de la unidad de control es útil representar el estado de

las señales de gobierno utilizadas por la instrucción a través del tiempo, en lo que se

denomina un cronograma. En los cronogramas, el eje horizontal representa el transcurso

del tiempo y en el vertical se representa el voltaje o estado activado/alto y desactiva-

do/bajo de las diferentes señales. A su vez, en la parte superior se ha representado la

señal de reloj del computador.

34

Page 46: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

La señal de reloj ha sido dividida en cuatro diferentes fases (θ1,θ2,θ3,θ4), que a su

vez pueden ser agrupadas en dos etapas principales:

Ciclo de instrucción. Ocupa las fases θ1y θ2. Se lee de la memoria principal la

instrucción a ejecutar y se carga en el registro I.

Ciclo de operando. Ocupa las fases θ3yθ4y en dicho ciclo se realiza la búsqueda del

operando, la ejecución de la operación, y la preparación de la siguiente instrucción.

Figura 15: Cronograma de la instrucción suma

5.3. Código máquina

Las instrucciones que procesa un computador digital forman un lenguaje del tipo

denominado código máquina o código binario. Recordemos que el computador digital

maneja solo números binarios, de modo que el código máquina es directamente escrito en

binario. Como el código máquina del juego de instrucciones del computador, los lengua-

jes de código máquina son muy dependientes de la arquitectura de cada computador, y

por tanto el código de un programa es difícilmente transportable a otras arquitecturas.

El lenguaje de código máquina es el tipo de lenguaje más primitivo en que un

programa se puede escribir, y por ello es un lenguaje de bajo nivel, pues no está pensado

para que sea fácil de usar y entender por parte de un humano y es poco transportable.

Los lenguajes de más alto nivel son más transportables y fáciles de entender por las

personas. Una ventaja de los lenguajes de código máquina es que permiten escribir los

programas de la forma más e�ciente.

El computador en que se enmarca este proyecto tiene una longitud de instrucción

de 16 bits, que como ya se ha explicado se divide en 3 partes: el código de operación,

el modo de direccionamiento y el operador o dirección. El código de operación cuenta

con 4 bits, el modo de direccionamiento de un bit y el operador cuenta con 11 bits.

35

Page 47: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

En el cuadro 16 se puede ver el código de un pedazo de un programa. El programa

leerá dos números del teclado, los guardará en las posiciones de memoria 10 y 11, los

sumará y guardará el resultado en la posición de memoria 12, para �nalmente mostrar

el resultado en pantalla.

Si bien este programa es muy simple, realizar programas no mucho más complejos

en código binario se hace una tarea demasiado tediosa y cada vez más difícil. Por esa

razón se diseñaron lenguajes cada vez más sencillos de usar y entender. El próximo paso

en facilidad de uso es el código mnemotécnicos.

Dirección CO MD D Signi�cado

50 0100 0 000 0000 1010 Leer del teclado un númeroy guardarlo en la posiciónde memoria 10

51 0100 0 000 0000 1011 Leer del teclado un númeroy guardarlo en la posiciónde memoria 11

52 0010 0 000 0000 1010 Llevar al acumulador elvalor de la posición dememoria 10

53 0101 0 000 0000 1011 Sumar al acumulador elnúmero guardado en laposición de memoria 11

54 0001 0 000 0000 1100 Almacenar el valor delacumulador en la posiciónde memoria 12

55 0011 0 000 0000 1100 Escribir en pantalla el valorde la posición de memoria12

56 0000 0 000 0000 0000 Parar la máquina

Cuadro 16: Ejemplo de programa en código máquina para el computador

5.4. Lenguaje ensamblador

Un lenguaje ensamblador es un lenguaje de programación de bajo nivel que se usa

para programara computadores, microprocesadores, microcontroladores etc. Implemen-

ta una representación simbólica (o código mnemotécnico) de los códigos de máquina

binarios, así como de una serie de pseudoinstrucciones. El código máquina ha de ser

traducido a código máquina por un programa de traducción. Mientras que la traduc-

36

Page 48: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

ción de los códigos mnemotécnicos a código máquina es directa, las pseudoinstrucciones

requieren que el programa traductor realice tareas adicionales durante la traducción,

como por ejemplo situar constantes en posiciones concretas de la memoria, situar cier-

tas instrucciones a partir de cierta posición de memoria o traducción de etiquetas del

código ensamblador a posiciones de memoria de código máquina.

Tanto las instrucciones del procesador como los registros y posiciones de memoria,

y las pseudoinstrucciones, son especí�cos de cierta arquitectura de computador, con lo

que el código generado no es directamente portable a otra arquitectura diferente. Esta

es una característica común en lenguajes de bajo nivel.

El lenguaje ensamblador de la máquina virtual implementada en este proyecto cuen-

ta con las instrucciones de�nidas en los cuadros 17 y 18. En el cuadro 19 se muestra un

ejemplo de programa en código ensamblador.

A su vez el lenguaje ensamblador implementa las siguientes pseudoinstrucciones:

ORG Sirve para indicar en qu�é direcci�ón de memoria comenzar�án a colocarse las

instrucciones y espacios para datos y resultados al realizarse la traducci�ón. Permite

al programador o indicar de forma simple d�ónde va a ir ubicado su programa

dentro de la memoria.

ESP Sirve para dejar un espacio en la memoria en el cual no habr�á ninguna

instrucci�ón. Este tipo de espacios se utiliza para datos y resultados.

CTE Es similar a ESP pero adem�ás deja un valor en el espacio. Permite tener

constantes que el programa vaya a necesitar, por ejemplo el n�úmero dos en caso

de que se necesite realizar una media, etc.

FIN Indica al traductor que cese la traducci�ón. No debe confundirse con ALT que

es la instrucci�ón de parada de la m�áquina.

DRE Signi�ca Dirección Representada por la Etiqueta. Guarda como constante

en memoria la posición de memoria en que se encuentra la etiqueta que toma

como parámetro esta pseudoinstrucción.

37

Page 49: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

CO MD Código Operación realizada Transferencia entreregistros

0000 0 ALT Parar la máquina0001 0 ALM Almacenar el contenido del

acumulador en la memoria(A)→M(D), P→(P) + 1

0001 1 ALMI Almacenar indirectamente (A)→M(M(D)), P→(P) +1

0010 0 CAR Cargar de la memoria alacumulador

M(D)→A, P→(P) + 1

0010 1 CARI Cargar indirectamente M(M(D))→A, P→(P)+ 10011 0 ESC Escribir un entero en la

pantallaM(D)→E, P→(P) + 1

0011 1 ESCI Escribir indirectamente unentero en la pantalla

M(M(D))→E, P→(P) + 1

0100 0 LEE Leer un entero del teclado E→M(D), P→(P) + 10100 1 LEEI Leer indirectamente E→M(M(D)), P→(P)+10101 0 SUM Sumar al acumulador (A) + M(D)→A, P→(P) +

10101 1 SUMI Sumar indirectamente (A) + M(M(D))→A,

P→(P) + 10110 0 RES Restar al acumulador (A) - M(D)→A, P→(P) +

10110 1 RESI Restar indirectamente (A) - M(M(D))→A,

P→(P) + 10111 0 MUL Multiplicar por A (A)·M(D)→A, P→(P) + 10111 1 MULI Multiplicar indirectamente (A)·M(M(D))→A,

P→(P) + 11000 0 DIV Dividir el acumulador entre

el operando(A) / M(D)→A, P→(P) +1

1000 1 DIVI Dividir indirectamente (A) / M(M(D))→A,P→(P) + 1

1001 0 MOD Módulo del acumulador o yel operando

(A) mod M(D)→A, P→(P)+ 1

1001 1 MODI Módulo realizado oindirectamente

(A) mod M(M(D))→A,P→(P) + 1

1010 0 SAL Salto incondicional (D)→P1010 1 SALI Salto incondicional

indirectoM(D)→P

Cuadro 17: Las columnas indican el código de operación, modo de direccionamiento, elcódigo mnemotécnico y una somera explicación para cada una de las instrucciones deCESIUS.

38

Page 50: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

CO MD Código Operación realizada Transferencia entreregistros

1011 0 SAN Salto si A es negativo (D)→P si (A)<0si no P→(P) + 1

1011 1 SANI Salto indirecto si A esnegativo

M(D)→P si (A)<0si no P→(P) + 1

1100 0 SAC Salto si A es cero (D)→P si (A)=0si no P→(P) + 1

1100 1 SACI Salto indirecto si A es cero M(D)→P si (A)=0si no P→(P) + 1

1101 0 SAP Salto si A es positivo (D)→P si (A)>0si no P→(P) + 1

1101 1 SAPI Salto indirecto si A espositivo

M(D)→P si (A)>0si no P→(P) + 1

1110 0 ECA Escribir carácter a en lapantalla

M(D)→E, P→(P) + 1

1110 1 ECAI Escribir car�ácter aindirectamente

M(M(D))→E, P→(P) + 1

1111 0 LCA Leer carácter E→M(D), P→(P) + 11111 1 LCAI Leer carácter a

indirectamenteE→M(M(D)), P→(P)+1

Cuadro 18: Las columnas indican el código de operación, modo de direccionamiento, elcódigo mnemotécnico y una somera explicación para cada una de las instrucciones deCESIUS (Continuación).

Instrucción Dirección CO MD D

LEER 10 20 0100 0 00000001010LEER 11 21 0100 0 00000001011

CARGAR 10 22 0010 0 00000001010SUMAR 11 23 0101 0 00000001011

ALMACENAR 12 24 0001 0 00000001100ESCRIBIR 12 25 0011 0 00000001100PARAR 26 0000 0 00000000000

Cuadro 19: Ejemplo de programa. A la izquierda se presenta una lista de las operacionesa efectuar, a la derecha se tiene el programa en la memoria. El contenido de los registrosde la memoria se ha separado en tres bloques (CO, MD y D) para facilitar el estudio,dicha separación no existe en la realidad.

39

Page 51: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

5.5. Ejemplos

5.5.1. Media de tres números

Este programa calcula la media de tres números. Primero el programa pide tres nú-

meros, los cuales almacena en memoria. Después calcula la media y �nalmente muestra

en pantalla dicha media. El cuadro 20 presenta el código ensamblador del programa, y

la �gura 16 el esquema de funcionamiento del mismo.

ORG 0SAL INI

A: ESP 1B: ESP 1C: ESP 1

TRES: CTE 3RES: ESP 1INI: LEE A

LEE BLEE CCAR ASUM BSUM CDIV TRESALM RESESC RESALTFIN

Cuadro 20: Código mnemoténico de programa que realiza media de tres números

40

Page 52: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 16: Esquema del funcionamiento del programa que realiza media de tres números

5.5.2. Cálculo de número primo

Este programa comprueba si un número es primo. En primer lugar el programa pide

un número N al usuario, que es guardado en memoria. Después el programa calcula si

el resto de dividir N entre los números 2 a N-1 es cero para alguno de ellos, en cuyo

caso N no sería primo. Si N es primo, el programa escribirá '0' en pantalla. Si es primo,

escribirá '1' en pantalla. El cuadro 21 presenta el código ensamblador del programa, y

la �gura 17 el esquema de funcionamiento del mismo.

41

Page 53: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

ORG 0SAL INI

PRIMO: ESP 1CONTADOR: CTE 2

SI: CTE 1NO: CTE 0INI: LEE PRIMO

BUCLE CAR PRIMORES CONTADORSAC PRINTSICAR PRIMOMOD CONTADORSAC PRINTNOCAR CONTADORSUM SIALM CONTADORSAL BUCLE

PRINTSI: ESC SIALT

PRINTNO: ESC NOALTFIN

Cuadro 21: Código Mnemotécnico de programa que calcula si un número es primo

Figura 17: Diagrama de funcionamiento delprograma que calcula si un número es primo

42

Page 54: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

5.5.3. Módulo al cuadrado de un vector

Este programa calcula el módulo de un vector de cuatro componentes. El programa

pide cuatro números como datos de entrada, los cuales guarda en memoria. Después

calcula la suma de los cuadrados de las componentes del vector, es decir, el módulo al

cuadrado del vector. Finalmente el programa muestra el número calculado en pantalla.

El cuadro 22 presenta el código ensamblador del programa, y la �gura 18 el esquema

de funcionamiento del mismo.

ORG 0SAL INI

VECTOR: ESP 4TAM: CTE 4RES: ESP 1PUN: ESP 1VPOS: DRE VECTORUNO: CTE 1INI: CAR VPOS

ALM PUNLEER: CAR VPOS

SUM TAMRES PUNSAC PRINTLEEI PUNCARI PUNMULI PUNSUM RESALM RESCAR PUNSUM UNOALM PUN

PRINT: ESC RESALTFIN

Cuadro 22: Código Mnemotécnico de programa que calcula el módulo al cuadrado deun vector de 4 componentes

43

Page 55: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 18: Diagrama de funcionamiento delprograma que calcula el módulo al cuadradode un vector de 4 componentes

5.5.4. Frase o palabra en orden inverso

Este programa pide caracteres como datos de entrada, los cuales guarda en memoria,

hasta que el usuario escriba un punto. Entonces el programa escribe los caracteres in-

troducidos en orden inverso. El cuadro 23 presenta el código ensamblador del programa,

y la �gura 19 el esquema de funcionamiento del mismo.

44

Page 56: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

ORG 0SAL INI

P: ESP 1PUNTO: CTE 46VPOS: DRE FRASEUNO: CTE 1INI: CAR VPOS

ALM PLEER: LCAI P

CARI PRES PUNTOSAC PRINTCAR PSUM UNOALM PSAL LEER

PRINT: CAR PRES VPOSSAC PARARCAR PRES UNOALM PECAI PSAL PRINT

PARAR: ALTFRASE: ESP 100

FIN

Cuadro 23: Programa que escribe una frase en orden inverso

45

Page 57: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 19: Diagrama de funcionamiento de programa que escribe una frase en ordeninverso

5.5.5. Lectura de una matriz

Este programa guarda en memoria una matriz. Para ello primero pide dos números

'm' y 'n' como parámetros de entrada, que corresponden con el número de �las y colum-

nas de dicha matriz. Se supone que m · n < 50. A continuación el usuario introduce los

elementos de dicha matriz. El cuadro 24 presenta el código ensamblador del programa,

y la �gura 20 el esquema de funcionamiento del mismo.

46

Page 58: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

ORG 0SAL INI

M: ESP 1N: ESP 1

MATA: ESP 50DCM: DRE MATAK: ESP 1J: ESP 1

PUN: ESP 1UNO: CTE 1INI: LEE M

LEE NCAR UNOALM K

BUCLK: CAR UNOALM J

BUCLJ: CAR KRES UNOMUL NSUM JRES UNOSUM DCMALM PUNLEEI PUNCAR JSUM UNOALM JRES NSAN BUCLJSAC BUCLJCAR KSUM UNOALM KRES MSAN BUCLKSAC BUCLKALTFIN

Cuadro 24: Programa que almacena una matriz

47

Page 59: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 20: Diagrama de funcionamiento de programa que almacena una matriz

5.5.6. Submatriz triangular

Programa que lee una matriz y luego escribe los elementos de su submatriz trian-

gular inferior en el orden indicado en la �gura. La submatriz triangular inferior está

formada por los elementos de la diagonal de la matriz y los de debajo. Los cuadros

25 y 26 presenta el código ensamblador del programa, y la �gura 21 el esquema de

funcionamiento del mismo.

48

Page 60: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

ORG 0SAL INI

M: ESP 1N: ESP 1

MATA: ESP 50DCM: DRE MATAK: ESP 1J: ESP 1

PUN: ESP 1UNO: CTE 1INI: LEE M

LEE NCAR UNOALM K

BUCLK: CAR UNOALM J

BUCLJ: CAR KRES UNOMUL NSUM JRES UNOSUM DCMALM PUNLEEI PUNCAR JSUM UNOALM JRES NSAN BUCLJSAC BUCLJCAR KSUM UNOALM KRES MSAN BUCLKSAC BUCLKCAR UNOALM K

BSK: CAR UNOALM J

Cuadro 25: Programa que lee una matriz y luego escribe los elementos de su submatriztriangular

49

Page 61: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

BSJ: CAR KRES UNOMUL NSUM JRES UNOSUM DCMALM PUNESCI PUNCAR JSUM UNOALM JRES KSAN BSJSAC BSJCAR KSUM UNOALM KRES MSAN BSKSAC BSKALTFIN

Cuadro 26: Programa que lee una matriz y luego escribe los elementos de su submatriztriangular (continuación)

50

Page 62: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 21: Diagrama de funcionamiento de programa que lee una matriz y luego escribelos elementos de su submatriz triangular

51

Page 63: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

52

Page 64: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

6. Estructura del emulador

El programa desarrollado es un emulador de un computador digital sencillo deno-

minado Xenon, que cuenta con las instrucciones de código máquina que se han descrito

en secciones previas. Este programa está implementado en lenguaje Java, lo cual per-

mite que un mismo ejecutable pueda ser usado sin modi�cación alguna en muy diversas

arquitecturas y sistemas operativos. Este programa no solo sirve como emulador de

dicho computador, sino como plataforma de desarrollo y depuración de aplicaciones en

lenguaje ensamblador para dicho computador. Existen tres partes diferenciadas en este

programa, que corresponden con tres vistas diferentes de la aplicación:

Vista de desarrollo: Esta vista permite al usuario crear y gestionar proyectos y

código ensamblador, además de permitir acceder al resto de vistas. Desde esta

vista será posible compilar el código ensamblador para pasarlo a código binario.

Vista de depuración: Desde la vista de depuración, el usuario puede controlar

la ejecución de un programa. El depurador puede abrir tanto archivos en código

ensamblador como en código binario.

Vista de emulación: Esta vista abre el emulador del computador digital. Puesto

que el computador digital solo entiende código binario, el emulador solo es capaz

de ejecutar código binario.

La sección de manual de usuario describe de forma más detallada el aspecto visual de

cada vista. Tal y como describe la sección de manual de usuario, el programa cuenta

con dos ejecutables. El ejecutable xenon.main.jar abre la vista de desarrollo, desde la

cual se puede acceder a las demás vistas. El ejecutable xenon.emu.jar es una versión

standalone del emulador, de forma que no sea necesario abrir el entorno de desarrollo

para emular la ejecución de un programa en el computador digital.

6.1. Código ensablador y código binario

Los dos lenguajes que entiende este computador son el código ensamblador y el

código binario de�nidos en anteriores secciones. Sin embargo, como el computador di-

gital descrito, llamado Xenon, no tiene implementación física, estos códigos han de ser

guardados por el emulador en algún formato que sea capaz de entender el programa

emulador.

53

Page 65: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

El código ensamblador es guardado en �cheros de texto, de forma que cada ins-

trucción es contenida en una línea. El tamaño de estos �cheros dependerá de cuántas

líneas de código tenga dicho programa. El código ensamblador es guardado en �cheros

de texto con extensión �ls2�.

En cambio, el código binario es guardado en un archivo binario. Recordemos que

el computador tiene una capacidad de direccionamiento de la memoria principal de 11

bits, contando con 2048 posibles direcciones de memoria. A su vez la longitud de un

registro de memoria es de 16bits, o 2 bytes.Los �cheros de código binario contienen una

copia del contenido de toda la memoria principal del computador. Estos archivos están

en formato binario, de modo que los primeros 2 bytes corresponden a la dirección de

memoria 0, los siguientes 2 bytes corresponden a la dirección de memoria 1 y así hasta

llegar a la última dirección de memoria, 2047. Como se puede comprobar, el formato de

los archivos de código binario del computador Xenon es muy sencillo. Dichos �cheros

tienen una extensión �ece� que los identi�ca. Además, todos los archivos de código

binario tendrán el mismo tamaño, pues el tamaño de la memoria principal no cambia y

los archivos de código binario contienen una copia bit a bit de dicha memoria, de forma

secuencial.

6.2. Clases

El código está documentado en doxygen van Heesch, Dimitri (1997), de forma que

sea fácil de entender. Las clases principales implementadas en el código son:

Interface. Es la clase principal del ejecutable xenon.main.jar, por ello contiene una

función main. De�ne una ventana que contiene un JPanel con un CardLayout,

que permite alternar entre las vistas de desarrollo y depuración dentro de una

misma ventana.

ProjectsManager. Gestiona el árbol de proyectos de la vista de desarrollo.

TabsManager. Gestiona las pestañas de los archivos abiertos en la vista de desa-

rrollo.

DebugViewManager. Implementa la vista de depuración.

Sobre. Esta clase implementa una ventana popup que muestra información sobre

el autor del proyecto, así como del profesor tutor del mismo.

54

Page 66: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Emulator. Es la clase principal del ejecutable xenon.emu.jar, por ello contiene una

función main. Esta clase es la principal de la vista de emulación. La vista de emu-

lación es accesible tanto desde la vista de desarrollo del ejecutable xenon.main.jar

como desde el ejecutable xenon.emu.jar de forma standalone.

ButtonTabComponent. Esta clase es usada por cada pestaña, en la vista de desa-

rrollo. Permite mostrar el nombre del archivo de una pestaña, así como un botón

con una X que sirve para cerrar dicha pestaña.

XenonHelper. En esta clase se encuentran métodos que permiten compilar código

ensamblador, así como la lectura e interpretación de código binario.

Instruction. Una instancia de esta clase contendrá toda la información de una

instrucción: la posición de memoria en que se encuentra, el código de operación

y el operador de la instrucción.

PopupListener. Implementa un listener que muestra un popup cuando se hace

click derecho con el ratón en cierto objeto.

Project. De�ne un proyecto y sus propiedades básicas.

ProjectFile. De�ne un �chero perteneciente a un proyecto.

Tab. Implementa una pestaña que muestra un archivo, en la vista de desarrollo.

VirtualComputer. Es una abstracción del funcionamiento del computador Xenon.

El emulador y el depurador usan una instancia de esta clase para ejecutar cada

instrucción.

Las siguientes clases tienen como objetivo conectar visualmente con líneas y �echas

componentes grá�cos en un JPanel, de forma sencilla. Este código es una modi�cación

del código de Stanislav Lapitsky Lapitsky, Stanislav (2007).

JConnector. Clase principal del conector que conecta dos objetos con �echas.

ConnectorContainer. Extensión de JPanel que permite añadir conectores con �e-

chas entre objetos contenidos en dicho JPanel.

ConnectLine. De�ne una línea usada por un JConnector.

55

Page 67: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Para hacerse una primera idea de la estructura del programa, la �gura 22 es un diagrama

de clases UML del código que incluye las clases anteriormente mencionadas. Cuando

dos clases son conectadas por una �echa, como DebugViewManager→VirtualComputer,

signi�ca que DebugViewManager tiene un atributo que es una instancia de la clase

VirtualComputer. A su vez, a un lado de dicha �echa se sitúa el nombre de dicho

atributo.

Figura 22: Diagrama de clases de las clases principales

6.2.1. Interface

Es la clase principal del ejecutable Xenon.main.jar, por ello contiene una función

main. De�ne una ventana que contiene un JPanel con un CardLayout, que permite

alternar entre las vistas de desarrollo y depuración dentro de una misma ventana. La

�gura 23 muestra un diagrama de la clase. El punto de partida del programa es el

método main(), que crea una instancia de la clase Interface. El constructor de Interface

a su vez llama al método addComponentToPane().

Interface de�ne la clase SliderListener, que tiene como objeto actualizar la frecuen-

cia de ejecución del computador cuando el usuario mueve el deslizador que marca la

56

Page 68: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 23: Diagrama de la clase Interface

frecuencia en la vista de depuración.

Los atributos de la clase Interface son:

JPanel cardPanel. Panel que usa un layout de tipo CardLayout para poder cam-

biar entre la vista de depuración y de código.

String state. Variable que informa de si estamos actualmente en la vista de código

o de depuración.

JTree projectsTree. Árbol de proyectos, muestra los proyectos y los archivos con-

tenidos en cada proyecto.

TabsManager tabsManager. Gestor de pestañas. Cada pestaña permite visualizar

un archivo que pertenece a alguno de los proyecto abiertos.

DebugViewManager debugViewManager. Controlador principal de la vista de de-

puración.

JTextArea problemasArea. Área que informa de problemas en la vista de desa-

rrollo, como por ejemplo problemas de compilación.

ProjectsManager projectsManager. Clase gestora de los proyectos abiertos.

JSlider slider. Slider que sirve para cambiar la frecuencia de ejecución del compu-

tador.

Los métodos que de�ne la clase Interface son:

main(). Lanza la aplicación, creando una instancia de Interface.

57

Page 69: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Interface(). De�ne la posición de la ventana en pantalla, asigna el título de la

ventana y llama al método addComponentToPane().

addComponentToPane() se encarga de inicializar los atributos de Interface, ins-

tanciando por ejemplo el gestor de la vista de depuración y el gestor del árbol

de proyectos y de las pestañas de la vista de desarrollo. Este método se encarga

no solo de inicializar los atributos de la clase sino de dar contenido a la ventana,

añadiendo los menús, las barras de herramientas y demás objetos que se pueden

ver en las vistas de desarrollo y depuración.

6.2.2. ProjectsManager

Figura 24: Diagrama de la clase ProjectsManager

La vista de desarrollo contiene un árbol de proyectos. En ese árbol se muestran los

proyectos abiertos, y en un nivel del árbol inferior, los archivos contenidos en dichos

proyectos. La clase ProjectsManager gestiona dicho árbol de proyectos, y una instancia

de esta clase es asignada al atributo projectsManager de la clase Interface. La �gura 24

muestra un diagrama de esta clase.

Esta clase contiene una serie de atributos:

ArrayList<Project> projectsList. Lista de proyectos abiertos.

Project currentlySelectedProject. Proyecto seleccionado actualmente. Esta infor-

mación es útil para realizar acciones como cerrar proyecto o para compilar.

58

Page 70: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

ProjectFile currentlySelectedFileInTree. Fichero actualmente seleccionado en el

árbol de proyectos. Este atributo es usado en acciones como depurar, compilar,

emular, o guardar o cerrar archivo.

JTree projectsTree. Es el árbol de proyectos, es el objeto que es mostrado en

pantalla.

TabsManager tabsManager. Gestor de pestañas. Es necesario por ejemplo para

poder todas las pestañas relacionadas con el proyecto al ejecutar la acción cerrar

proyecto.

Respecto de los métodos de la clase ProjectsManager:

En el constructor se inicializan todos los atributos de la clase. Los métodos getPro-

jectsTree(), getCurrentlySelectedProject(), y getCurrentlySelectedFileInJTree()

son métodos get que devuelven los atributos de la clase correspondientes.

Los métodos mouseClicked(), mouseEntered(), mouseExited(), mousePressed(), y

mouseReleased() implementan la interfaz MouseListener. Concretamente usare-

mos mousePressed() de forma que un click con el ratón seleccione un proyecto o

archivo en el árbol de proyectos, y un doble click abra el �chero clickeado.

El método closeProject() elimina el proyecto actualmente seleccionado del árbol

de proyectos, a la vez que cierra las pestañas abiertas relacionadas con dicho

proyecto.

El método removeFileFromJTree() elimina un �chero, que es parámetro de entrada

de dicho método, del árbol de proyectos. Este método es llamado por el gestor de

pestañas cuando

addBinaryFromCode() es usado para añadir un �chero binario al árbol de proyec-

tos que tenga el mismo nombre que un �chero de código ensamblador, pero con

la extensión �ls2�.

createProject() muestra un diálogo para elegir el nombre y ubicación del proyecto

a crear, y después lo crea, añadiendo un �chero de código ensamblador al mismo.

openProject() abre un proyecto situado en el directorio que el parámetro de en-

trada contiene.

59

Page 71: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

6.2.3. TabsManager

Figura 25: Diagrama de la clase TabsManager

Esta clase permite gestionar el conjunto de archivos abiertos para su edición, los

cuales se muestran en pestañas en la vista de desarrollo. Contiene un solo atributo

privado, tabbedFilePane, que es el panel con todas las pestañas. La �gura 25 muestra

un diagrama de esta clase. Los métodos de esta clase son:

getTabbedPane(). Devuelve el panel de pestañas, el atributo tabbedFilePane.

TabsManager(JTabbedPane tab). Constructor, inicializa el atributo tabbedFile-

Pane de la clase.

searchTab(ProjectFile p�le). Busca una pestaña que contenga el �chero p�le.

dontAskAndRemoveTab(Tab t). Elimina la pestaña sin preguntar si quieres guar-

dar el �chero.

askAndRemoveTab(Tab t). Si el �chero ha sido modi�cado, pregunta si quieres

guardarlo. Entonces lo cierra.

removeTab(ButtonTabComponent ct). Elimina una pestaña a partir de su etique-

ta ButtonTabComponent, que contiene el nombre del archivo y el botón en forma

de X que sirve para cerrarla.

60

Page 72: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

addTab(ProjectFile p�le) Este método añadirá una pestaña al panel de pestañas

si no existe una pestaña con el �chero p�le. En otro caso seleccionará y mostrará

dicha pestaña.

saveTabTo(Tab t, String path). Guarda el �chero de una pestaña t en la ruta

path.

saveCurrentlySelectedTab(). Guarda el �chero de la pestaña actualmente selec-

cionado.

getCurrentlySelectedTab(). Devuelve la pestaña actualmente seleccionada, o null

si no existe ninguna pestaña.

saveCurrentlySelectedTabAs(). Crea un diálogo que pregunta dónde se quiere

guardar el texto de la actual pestaña, y lo guarda.

saveAllTabs(). Guarda los cambios realizados en los �cheros de todas las pestañas.

saveIfModi�ed(ProjectFile codeToDebug). Comprueba si el �chero ha sido modi-

�cado y pregunta al usuario si quiere guardar los cambios.

closeAllTabsOfProject(Project p). Cierra todas las pestañas del proyecto p.

closeCurrentlySelectedTab(). Cierra la pestaña actualmente seleccionada.

closeAllTabs(). Cierra todas las pestañas, preguntando si guardar cambios en

aquellos �cheros que se han modi�cado.

6.2.4. DebugViewManager

Clase gestora de la vista de depuración. Esta clase realiza todas las tareas de la

interfaz grá�ca de la vista de depuración, además de lidiar con la clase VirtualComputer.

La �gura 26 muestra un diagrama de esta clase. En esta clase se de�nen otras subclases

y enumeraciones:

Base es una enumeración que indica la base de representación numérica de los

registros y de la memoria principal del computador.

InputType es una enumeración que indica si el computador está pidiendo un

carácter o número como dato de entrada o no está pidiendo datos.

61

Page 73: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 26: Diagrama de la clase DebugViewManager

62

Page 74: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

La clase Trace permite crear una traza de la ejecución de un programa. Escribe en

un �chero �traza.txt� en el directorio del proyecto el resultado de cada operación

realizada: el valor de los registros del computador, la dirección de la operación y

la operación.

ExecuteInstructionTask es una clase que extiende la clase TimerTask. En Debug-

ViewManager, una instancia de este clase es usada para llamar de forma periódica

al computador virtual para que ejecute la siguiente instrucción.

TableListener. Clase que escucha cuándo se selecciona una nueva posición de

memoria. Cuando el usuario seleccione una posición de memoria en la tabla, el

registro P cambiará su valor.

ConsoleKeyListener. Clase que escucha la entrada del teclado y la representa

en la consola, e implementa la interfaz KeyListener. Cuando el usuario presione

ENTER, los datos se mandarán al computador.

ColorCellRenderer. Esta clase sirve para resaltar las posiciones de memoria que

cambian en la JTable correspondiente.

FlashySignal. Versión de JLabel que sirve para marcar cuándo se usan las señales

del computador.

FlashyTextField. Versión de JTextField que marca en rojo cuando un registro es

actualizado.

Atributos de la clase:

JTextPane consolaPane. Es la consola de entrada y salida de datos.

ConsoleKeyListener consolaListener. Listener que recoge y trata la entrada pro-

veniente del teclado.

String inputBu�er. Bu�er de entrada. Se van añadiendo datos hasta recibir un

enter (en el caso de que el computador esté pidiendo datos).

long period. Período de reloj de una instrucción del computador en milisegundos,

1000/f(Hz).

int runTo. En el caso de "Ejecutar Hasta", dirección de memoria en la que parar

la ejecución.

63

Page 75: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

ColorCellRenderer pTableRenderer, memoriaTableRenderer. Renderers de las ta-

blas pTable y memoriaTable.

Timer instructionTimer. Timer usado para organizar la ejecución de instrucciones

en modo runMode.

Timer changesTimer. Timer usado para los cambios de registro.

ExecuteInstructionTask instructionTask. Tarea de ejecución de una instrucción.

Base base. Variable que contiene la base que actualmente se usa para representar

datos.

VirtualComputer computer. Instancia del computador que se está emulando.

Los métodos de la clase son:

setPidiendoDatos(InputType b). Método que sirve para dar a conocer a la vista

de depuración si el computador está a la espera de datos.

setRegistersBase(Base b). Método que cambia la base en que se muestran los

datos.

setExecutionPeriod(long millisecs). Método que cambia el período de ejecución.

Este cambio de período se notará la siguiente vez que se ejecute el código en modo

"Ejecutar todo" o "Ejecutar hasta".

getConsoleInput(). Devuelve los datos del bu�er de entrada del teclado.

addConsoleOutput(String text). Añade el texto del parámetro text a la consola.

selectNextInstructionInMemoryNearP(int p). Centra la tabla pTable en la posi-

ción indicada por el parámetro de entrada p.

actionRun(). Acción "Ejecutar Todo". Ejecuta las instrucciones del ordenador

hasta llegar a un ALT, con la frecuencia del computador seleccionada.

actionRunTo(int num). Acción "Ejecutar Todo". Ejecuta las instrucciones del

ordenador hasta llegar a cierta instrucción, * o a un ALT, con la frecuencia del

computador seleccionada.

actionPause(). Acción Pausar. Detiene la ejecución de instrucciones.

64

Page 76: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

actionRestart(). Acción Reiniciar. Reinicia el estado del computador.

actionExecuteNextInstruction(). Acción Ejecutar siguiente instrucción. Solo eje-

cuta una instrucción.

changeMemoryAddress(Instruction i). Cuando cierta posición de memoria cambia,

este método es llamado para actualizar la �la adecuada de tabla de memoria de

la interfaz grá�ca.

updateJTableModel(). Cuando muchas posiciones de memoria cambian, este mé-

todo es llamado para actualizar la tabla de memorian entera de la interfaz grá�ca.

setDebugCode(ArrayList<Instruction> codeArray, File �le). Inicializa la memo-

ria del computador con cierto código.

DebugViewManager(). Constructor de la vista depuración.

Los siguientes métodos son implementaciones de la interfaz VirtualComputer.VirtualComputerListener

que es el Listener del computador:

writeNumberToScreen(). Este método es llamado cuandoquiera que el compu-

tador quiera escribir números en pantalla.

stateChanged(). Este método es llamado cuandoquiera que el estado del compu-

tador cambie.

addZeros(String s, int a). Añade ceros a la cadena 's' hasta que dicha cadena

tenga una longitud 'a'.

memoryChanged(Instruction i). Este método será llamado cuando el contenido

de la dirección de memoria i cambie.

writeCharacterToScreen(). Este método será llamado cuandoquiera que el compu-

tador quiera escribir un carácter en pantalla.

6.2.5. Sobre

Esta clase implementa una ventana popup que muestra información sobre el autor

del proyecto, así como del profesor tutor del mismo. Esta clase es muy simple, y consta

de un constructor y de un método. En el constructor se pasan dos parámetros, que son

la posición x e y en la pantalla. A su vez, el método actionPerformed(ActionEvent e)

sirve para cerrar el popup. La �gura 27 muestra un diagrama de esta clase.

65

Page 77: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 27: Diagrama de la clase Sobre

6.2.6. Emulator

Figura 28: Diagrama de la clase Emulator

Es la clase principal del ejecutable Xenon.emu.jar, por ello contiene una función

main. Esta clase es la principal de la vista de emulación. La vista de emulación es

accesible tanto desde la vista de desarrollo del ejecutable xenon.main.jar como desde el

ejecutable xenon.emu.jar de forma standalone. Esta clase realiza todas las tareas de la

interfaz grá�ca de la vista de emulación, además de lidiar con la clase VirtualComputer,

que es la que ejecuta cada instrucción del computador. A nivel de código, es una versión

más sencilla que el DebugViewManager, pues el usuario no visualiza los registros ni

las posiciones de memoria ni tiene un control de la ejecución como en el modo de

depuración. La �gura 28 muestra un diagrama de esta clase.

Esta clase de�ne una serie de subclases:

ExecuteInstructionTask es una clase que extiende la clase TimerTask. Una instan-

cia de este clase es usada para llamar de forma periódica al computador virtual

66

Page 78: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

para que ejecute la siguiente instrucción.

ConsoleKeyListener. Clase que escucha la entrada del teclado y la representa

en la consola, e implementa la interfaz KeyListener. Cuando el usuario presione

ENTER, los datos se mandarán al computador.

BinaryFilter. Sirve de �ltro para mostrar solo los �cheros con la extensión binaria

"ece". A diferencia del DebugViewManager, que permite depurar tanto código bi-

nario como código ensamblador, el emulador solo permite ejecutar código binario.

Atributos de la clase:

JTextPane consoleArea. Es la consola de entrada y salida de datos.

ConsoleKeyListener consolaListener. Listener que recoge y trata la entrada pro-

veniente del teclado.

String inputBu�er. Bu�er de entrada. Se van añadiendo datos hasta recibir un

enter (en el caso de que el computador esté pidiendo datos).

long period. Período de reloj de una instrucción del computador en milisegundos,

1000/f(Hz).

Timer timer. Timer usado para organizar la ejecución de instrucciones.

ExecuteInstructionTask task. Tarea de ejecución de una instrucción.

VirtualComputer computer. Instancia del computador que se está emulando.

boolean exitOnClose. Si el emulador se está ejecutando en forma standalone,

cerrar la ventana cerrará todoel programa, en ese caso esta variable será true.

Los métodos de la clase son:

� getConsoleInput(). Devuelve los datos del bu�er de entrada del teclado.

setMyTitle(String s). Método que cambia el título de la ventana del emulador.

Sirve para añadir al título del emulador el archivo abierto.

Emulator(). Es el constructor que inicializa la clase. Inicializa los atributos de

la clase, luego llama a addComponentToPane(), que añade todos los elementos

grá�cos necesarios a la ventana, incluyendo el menú, la barra de herramientas y la

consola. addComponentToPane(Container pane). Añade todos los componentes

visuales necesarios al panel.

67

Page 79: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

addConsoleOutput(String text). Añade el texto del parámetro text a la consola.

setPidiendoDatos(InputType b). Método que sirve para dar a conocer a la vista

de depuración si el computador está a la espera de datos.

actionExecuteNextInstruction(). Acción Ejecutar siguiente instrucción. Solo eje-

cuta una instrucción.

actionPause(). Acción Pausar. Detiene la ejecución de instrucciones.

setRunCode(ArrayList<Instruction> codeArray). Inicializa la memoria del compu-

tador con cierto código.

actionRestart(). Acción Reiniciar. Reinicia el estado del computador.

actionRun(). Acción "Ejecutar Todo". Ejecuta las instrucciones del ordenador

hasta llegar a un ALT, con la frecuencia del computador seleccionada.

Los siguientes métodos son implementaciones de la interfaz VirtualComputer.VirtualComputerListener

que es el Listener del computador:

writeNumberToScreen(). Este método es llamado cuandoquiera que el compu-

tador quiera escribir números en pantalla.

stateChanged(). Este método es llamado cuandoquiera que el estado del compu-

tador cambie.

addZeros(String s, int a). Añade ceros a la cadena 's' hasta que dicha cadena

tenga una longitud 'a'.

memoryChanged(Instruction i). Este método será llamado cuando el contenido

de la dirección de memoria i cambie.

writeCharacterToScreen(). Este método será llamado cuandoquiera que el compu-

tador quiera escribir un carácter en pantalla.

68

Page 80: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

6.2.7. VirtualComputer

Figura 29: Diagrama de la clase VirtualComputer

Es una abstracción del funcionamiento del computador Xenon. El emulador y el

depurador usan una instancia de esta clase para ejecutar cada instrucción. Esta clase

mantiene la memoria principal del computador, así como el valor de sus registros. Cuan-

do se ejecuta una instrucción, los registros y la memoria principal cambian de acuerdo

con el funcionamiento de�nido para el computador. La �gura 29 muestra un diagrama

de esta clase. En VirtualComputer se de�nen una serie de clases y enumeraciones:

69

Page 81: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

VirtualComputerListener. Listener del computador, sirve para avisar de que el

computador ha cambiado de estado, o de que el computador quiere escribir en

pantalla.

ComputerSignal. Enumeración de las señales del computador.

ComputerRegister. Enumeración de los registros del computador.

ComputerState. Clase que de�ne el estado del computador, a nivel de registros

y señales del mismo. Contiene un listener del computador virtual, el valor de los

registros, un mapa que contiene qué registros han cambiado y otro que contiene

qué señales se han activado.

Los atributos de la clase son:

Instruction[] memoryMap. Mapa de memoria del computador.

Instruction[] InitialMemoryMap. Mapa de memoria inicial del computador. Este

dato se guarda para poder retornar el computador al estado inicial.

ComputerState state. Estado del computador.

boolean tra�cLight. Semáforo que asegura una ejecución ordenada.

En cuanto a los métodos de la clase:

VirtualComputer(). Constructor del computador, inicializa variables.

VirtualComputer(ArrayList<Instruction> memory). Constructor del computador

que inicializa la memoria con el parámetro de entrada 'memory'.

restart(). Lleva el ordenador al estado inicial. Pone a cero los registros y las señales,

y devuelve la memoria principal a su estado inicial.

setListener(VirtualComputerListener l). Asigna un nuevo listener al computador.

getListener(). Devuelve el listener del computador.

setMemoryMap(ArrayList<Instruction> memory). Modi�ca la memoria del compu-

tador con el parámetro 'memory'.

setMemoryMapToZero(). Inicializa a cero la memoria del computador.

70

Page 82: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

getMemoryMap(). Devuelve el mapa de memoria del computador.

getIndirectAddress(int d). Devuelve M(D), la dirección de memoria contenida en

la posición D.

getNextInstruction(). Devuelve la próxima instrucción a ejecutar, posición que

marca el registro P.

executeNextInstruction(). Método que ejecuta la siguiente instrucción. Este mé-

todo solo se ejecutará si el semáforo tra�cLight es false, y la ejecución del método

asigna true al semáforo. De este modo se impide en todo caso la ejecución de este

método de forma concurrente.

6.2.8. ButtonTabComponent

Figura 30: Diagrama de la clase ButtonTabComponent

Esta clase es usada por cada pestaña, en la vista de desarrollo. Permite mostrar

el nombre del archivo de una pestaña, así como un botón con una X que sirve para

cerrar dicha pestaña. En ButtonTabComponent se de�ne la clase TabButton, que crea

un botón con una x que cierra la pestaña. La �gura 30 muestra un diagrama de esta

clase.

ButtonTabComponent contiene tres atributos:

TabsManager manager. Es necesario conocer este dato para poder llamar al mé-

todo del gestor de pestañas con el �n de cerrar la pestaña al presionar el botón

x.

JLabel label. Etiqueta con el nombre del archivo de la pestaña.

71

Page 83: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

MouseListener buttonMouseListener. Es una implementación de un MouseAdap-

ter que cierra la pestaña cuando se hace click en el botón x, además de resaltar

dicho botón cuando el ratón pasa por encima.

Los dos métodos de la clase ButtonTabComponent son getLabel(), que devuelve el valor

de la etiqueta de la pestaña que contiene el nombre del archivo abierto; y el constructor

de la clase, que inicializa las variables, añadiendo la etiqueta con el nombre del archivo

de la pestaña, y el botón x de cerrar pestaña.

6.2.9. XenonHelper

Figura 31: Diagrama de la clase XenonHelper

En esta clase se encuentran métodos que permiten compilar código ensamblador,

así como la lectura e interpretación de código binario. Esta clase no contiene ningún

atributo y todos sus métodos son estáticos. La �gura 31 muestra un diagrama de esta

clase. En esta clase se de�nen:

La enumeración PseudoInstruction. Enumera las pseudoinstrucciones válidas en

lenguaje ensamblador.

Los métodos de la clase son:

generateMemoryMap(ArrayList<Instruction> in). Este método recoge la salida

del método translateToInstructions(String) y lo convierte en un mapa de memoria.

72

Page 84: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

ArrayList<Instruction> translateToInstructions(String code). Lee una cadena de

texto y la traduce a instrucciones. Es el método principal en la compilación de

código ensamblador a código binario.

searchLabel(ArrayList<LineCode> lineCodeArray, String addressLabel). Busca

etiqueta en una lista de líneas de código.

translateToBinary(ArrayList<Instruction> code). Traduce a binario un progra-

ma, una vez tenemos las instrucciones que lo forman. Este es el principal método

que permite guardar en formato �ece� el código binario de un programa.

intToByte(int i). Método usado para convertir de int a byte.

byteToInt(byte b). Método usado para convertir de byte a int.

translateFromBinary(byte[] binary). Traduce código binario a un mapa de me-

moria que contiene un programa. Es el método principal a la hora de leer código

binario y traducirlo a instrucciones que entienda el computador virtual Xenon.

openBinaryFile(File �le). Abre un �chero binario y devuelve el mapa de instruc-

ciones, haciendo uso del método translateFromBinary(byte[] binary).

saveToBinaryFile(File �le, ArrayList<Instruction> ins) . Guarda el código bi-

nario de un programa en formato "ece", para ello hace uso de translateToBi-

nary(ArrayList<Instruction> code).

6.2.10. LineCode

Figura 32: Diagrama de la clase LineCode

La clase LineCode. Contiene la información de una línea de texto del código en-

samblador. Es una clase intermediaria usada en la compilación del código ensamblador.

73

Page 85: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Contiene información como: la instrucción a la que se traduce la línea de código, el

número de línea, la pseudoInstrucción a la que se re�ere la línea de código, y etiqueta

(en formato texto) usada en dicha línea de código ensamblador. La �gura 32 muestra

un diagrama de esta clase.

6.2.11. Instruction

Figura 33: Diagrama de la clase Instruction

La clase Instruction de�ne una instrucción, así como una serie de métodos para

manejar dicha instrucción. Una instancia de esta clase contendrá toda la información

de una instrucción: la posición de memoria en que se encuentra, el código de operación

y el operador de la instrucción. La �gura 33 muestra un diagrama de esta clase.

Instruction contiene la enumeración OperationCode, que enumera todos los códi-

gos de operación posibles. Aquí, en código de operación se incluye tanto el código de

operación como el modo de direccionamiento, de forma que si por ejemplo el código de

operación es SUM y el modo de direccionamiento es directo, el OperationCode es SUM;

74

Page 86: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

y si es indirecto el OperationCode es SUMI.

Los atributos que contiene un objeto de la clase Instruction son:

OperationCode operationCode. Código de operación de la instrucción, e incluye

el modo de direccionamiento.

int insOperator. Operador de la instrucción (normalmente será una dirección de

memoria.

int data. Dato sin signo de 16 bit, correspondiente a la instrucción tal y como se

guarda en binario, pero en formato decimal. Contendrá un valor entre 0 y 65535.

Los números negativos se guardarán en complemento a 2 de 16bit.

int addressLocation. Posición de memoria en que se encuentra la instrucción,

tendrá un valor entre 0 y 2048 puesto que el direccionamiento es de 11 bits. Si no

se ha de�nido, la posición de memoria será -1.

Los métodos de la clase son:

Instruction(). Constructor que incializa todo a cero.

Instruction(OperationCode oc, int operator). Constructor que inicializa el conte-

nido de la instrucción (código+operador), pero no de�ne la posición de memoria

en que se encuentra la instrucción.

setInstruction(OperationCode oc, int operator). Método que inicializa el conteni-

do de la instrucción (código+operador), pero no de�ne la posición de memoria en

que se encuentra la instrucción.

setAddressLocation(int ma). Sitúa la instrucción en la posición de memoria 'ma'.

getAddressLocation(). Devuelve la posición de memoria de la instrucción.

setOperationCode(OperationCode oc). Método que cambia el código de operación

de la instrucción.

setInstructionOperator(int operator). Método que cambia el operador de la ins-

trucción.

setInstructionSigned(int d). Toma como entrada el dato (con signo) que corres-

ponde a la instrucción. El parámetro d debe pertenecer a [-32768, 32767] o lanzará

una excepción

75

Page 87: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

setInstructionUnsigned(int d). Toma como entrada el dato (sin signo) que corres-

ponde a la instrucción. El parámetro d debe pertenecer a [0, 65535] o lanzará una

excepción.

getOperationCode(). Devuelve el código de operación de la instrucción.

getInstructionOperator(). Devuelve el operador de la instrucción (en general será

una dirección de memoria).

getDataUnsigned(). Devuelve el dato guardado en memoria, sin signo, con un

valor entre 0 y 65535.

getDataSigned(). Devuelve el dato guardado en memoria, sin signo, con un valor

entre �32768 y 32767.

updateFromData(). Calcula qué código de operación y operador tiene la instruc-

ción a partir del dato guardado en memoria.

updateFromInstruction(). Calcula el dato a guardar en memoria, a partir del

código de operación y la dirección en memoria.

toString(). Crea una cadena que representa la instrucción.

6.2.12. PopupListener

Figura 34: Diagrama de la clase PopupListener

Esta clase extiende la clase MouseAdapter e implementa un listener que muestra un

popup cuando se hace click derecho con el ratón en cierto objeto. Como atributo tiene

JPopupMenu popup, que de�ne el popup a mostrar y es un parámetro que se pasa en el

constructor de la clase. Los demás métodos de�nidos sirven para mostrar dicho popup.

La �gura 34 muestra un diagrama de esta clase.

76

Page 88: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 35: Diagrama de la clase Project

6.2.13. Project

La clase Project de�ne un proyecto y sus propiedades básicas. Los únicos métodos

de�nidos en esta clase son el constructor, que inicializa los atributos de la clase, y el

método toString(), que da el nombre del �chero en formato cadena. La �gura 35 muestra

un diagrama de esta clase. Los atributos de la clase son:

File �le. Contiene el directorio donde está localizado el proyecto.

ArrayList <ProjectFile> projectFiles. Lista de �cheros pertenecientes al proyecto.

DefaultMutableTreeNode pnode. Nodo del proyecto en el árbol de proyectos.

6.2.14. ProjectFile

Figura 36: Diagrama de la clase ProjectFile

De�ne un �chero perteneciente a un proyecto. Esta clase de�ne la enumeración

FileType, que enumera los tipos de archivo que un �chero de un proyecto puede ser:

código binario, código ensamblador, o texto. La �gura 36 muestra un diagrama de esta

clase.

A su vez, un objeto de la clase ProjectFile contendrá los siguientes atributos:

DefaultMutableTreeNode fnode. Nodo de este �chero en el árbol de proyectos.

FileType type. De�ne el tipo de �chero.

77

Page 89: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

File �le. Ruta del �chero en el sistema de archivos.

Project project. Proyecto al que pertenece el �chero

Los métodos de esta clase:

ProjectFile(File f, Project p). Constructor, inicializa los atributos de la clase. Las

extensiones reconocidas para los �cheros de un proyecto son ls2 (código) y ece

(binario). El resto de archivos es tratado como texto.

toString(). Devuelve el nombre del �chero en una cadena.

setNode(DefaultMutableTreeNode no). Asigna 'no' como nodo de este �chero en

el árbol de proyectos.

6.2.15. Tab

Figura 37: Diagrama de la clase Tab

Implementa una pestaña que muestra un archivo, en la vista de desarrollo. Una pes-

taña mostrará un archivo, que pertenecerá a un proyecto abierto. La �gura 37 muestra

un diagrama de esta clase. Los atributos que un objeto de esta clase contendrá son:

ProjectFile pFile. Fichero que contiene la pestaña.

JTextArea textArea. Área de texto de la pestaña.

JLabel label. Etiqueta de la pestaña

boolean isModi�ed. Indica si el texto ha sido modi�cado y todavía no se ha

guardado.

78

Page 90: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Esta clase implementa una interfaz KeyListener, de forma que cuando el texto de la pes-

taña, la pestaña quede marcada mostrando que las modi�caciones del archivo realizadas

por el usuario no han sido guardadas todavía. Es por ello que se han añadido los méto-

dos keyPressed(KeyEvent arg0) , keyReleased(KeyEvent arg0), y keyTyped(KeyEvent

arg0).

Los demás métodos de esta clase son:

setLabel(JLabel l). Modi�ca la etiqueta de la pestaña.

isModi�ed(). Indica si hay cambios no guardados del �chero.

setModi�ed(boolean b). Marca el �chero como modi�cado/no modi�cado.

Tab(JTextArea ta, ProjectFile pf). Constructor que inicializa los atributos del

objeto.

6.2.16. JConnector

Figura 38: Diagrama de la clase JConnector

Clase principal del conector que conecta dos objetos con �echas. El constructor tiene

como parámetros los dos objetos JComponent a conectar mediante �echas, el tipo de

línea que los conecta y el color. La �gura 38 muestra un diagrama de esta clase.

79

Page 91: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

6.2.17. ConnectorContainer

Figura 39: Diagrama de la clase ConnectorContainer

Extensión de JPanel que permite añadir conectores con �echas entre objetos con-

tenidos en dicho JPanel. El panel que contiene el dibujo del computador digital en la

vista de depuración ha de ser de esta clase para poder pintar las �echas que conectan

los diferentes elementos del computador, como los registros, la memoria, los buses o las

señales de control. La �gura 39 muestra un diagrama de esta clase.

Contiene un atributo, ArrayList<JConnector> connectors, donde se guardan todos

los conectores. A su vez de�ne los siguientes métodos:

ConnectorContainer(). Constructor de la clase, inicializa el atributo connectors.

addConnector(JConnector c). Añade un conector al panel.

addConnectors(ArrayList<JConnector> c). Añade una lista de conectores al pa-

nel.

getConnectors(). Devuelve los conectores del panel.

paint(Graphics g). Pinta los conectores del panel.

80

Page 92: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

6.2.18. ConnectLine

Figura 40: Diagrama de la clase ConnectLine

De�ne una línea usada por un JConnector. Es la clase que se encarga de pintar la

línea de acuerdo a los parámetros establecidos, como por ejemplo el color, grosor de la

línea y los extremos con �echa. La �gura 40 muestra un diagrama de esta clase.

81

Page 93: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

82

Page 94: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

7. Manual de usuario

El programa tiene 3 vistas principales:

Vista de desarrollo: En esta vista se desarrolla el código ensamblador del compu-

tador. Desde esta vista se tiene acceso a las vistas de depuración y de emulación.

Vista de depuración: En esta vista se controla la ejecución del programa ensambla-

dor, teniendo acceso a los registros del computador y las posiciones de memoria.

Esta vista solo es accesible desde la vista de desarrollo.

Vista de emulación: En esta vista se ejecuta la emulación del computador, repre-

sentándose en la consola la entrada y salida de datos del computador. Esta vista

es accesible desde la vista de desarrollo y también se puede ejecutar de forma

autónoma.

7.1. Ejecución

Existen dos ejecutables, el entorno de desarrollo y el emulador. Los ejecutables java

son:

xenon.main.jar

xenon.emu.jar

Para ejecutarlos desde Linux, Mac o Windows, se pueden ejecutar desde la línea de

comandos:

$ java -jar xenon.main.jar

$ java -jar xenon.emu.jar

Otra opción en Linux es ejecutar los scriptsGite, Vivek (1999) main.sh y emu.sh.

En multitud de versiones de windows basta con hacer doble click sobre los archivos jar

para que estos se ejecuten.

7.2. Vista de desarrollo

Al iniciar el ejecutable xenon.main.jar, el programa muestra la vista de desarrollo.

Desde esta vista el usuario es capaz de desarrollar el código ensamblador, depurarlo,

así como entrar en el emulador. La vista cuenta con una barra de menú, una barra de

herramientas, un árbol de proyectos, una zona de edición y un cuadro de información.

83

Page 95: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

La mayoría de acciones posibles están disponibles tanto desde la barra de herramientas

como desde la barra de menú. La �gura 41 muestra la vista que el programa presenta

al iniciar el programa:

Figura 41: Vista inicial de desarrollo.

En la vista de la �gura 42 se puede observar un escenario típico en donde se han

abierto diversos proyectos, con un archivo de código abierto.

84

Page 96: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 42: Ejemplo de desarrollo

Figura 43: Barra de herramientas

La �gura 43 muestra la barra de herramientas. Desde la barra de herramientas se

tiene acceso a diversas acciones comunes:

Nuevo �chero. Crea un nuevo �chero dentro del proyecto que esté seleccionado.

Guardar. Guarda el �chero seleccionado.

Guardar como... Guarda el �chero seleccionado con un nuevo nombre.

Guardar todo. Guarda todos los �cheros modi�cados.

Abrir proyecto.

Cerrar proyecto.

85

Page 97: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Compilar. Compila el �chero de código fuente seleccionado. En caso de no haber

seleccionado un �chero con código fuente, compila el archivo de código fuente del

proyecto al que pertenece el �chero seleccionado.

Depurar. Abre la vista de depuración con las instrucciones del �chero de código

fuente o binario seleccionado.

Ejecutar. Abre la vista de emulación con las instrucciones del �chero binario

seleccionado.

Desde la barra de menús también se tiene acceso a todas las acciones. Como se puede

observar en la �gura 44, muchas de las acciones cuentan con combinaciones de teclas

de acceso rápido.

Figura 44: Barra de menús de la vista de desarrollo

7.3. Vista de emulación

La vista de emulación permite ejecutar código binario. En esta vista no se puede

controlar la ejecución de un programa, a diferencia de la vista de depuración. Tampoco

se puede visualizar los registros del computador ni los registros de la memoria principal.

El motivo es que uno no puede visualizar de forma directa los registros del computador

digital ni su memoria principal, a menos que el propio programa en ejecución esté

diseñado para hacerlo.

La vista cuenta con una barra de menú, una barra de herramientas que se puede ver

en la �gura 46, un árbol de proyectos, una zona de edición y un cuadro de información.

La mayoría de acciones posibles están disponibles tanto desde la barra de herramientas

como desde la barra de menú. La vista de ejecución está disponible tanto desde la vista

de desarrollo como de forma standalone desde el ejecutable xenon.emu.jar.

La �gura 45 la vista que el programa presenta al iniciar el programa:

86

Page 98: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 45: Vista de emulación

Figura 46: Barra de herramientas de la vista de emulación

Las acciones disponibles son:

Abrir ejecutable.Abre un ejecutable en formato de código binario de la máquina

Xenon.

Guardar texto de la consola. Guarda el texto mostrado en la consola.

Reiniciar máquina. Reinicia el programa así como el estado de los registros y

memoria principal de la computadora digital, limpiando el texto de la consola.

Salir. Si se está ejecutando el emulador en forma standalone, cierra todo el

programa. Si el emulador se ha abierto desde la vista de desarrollo, solo cierra la

vista de emulación.

Desde la barra de menús también se tiene acceso a todas las acciones. Dicha barra de

menús se presenta en la �gura 47.

87

Page 99: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 47: Barra de menús de la vista de emulación

7.4. Vista de depuración

La vista de depuración permite controlar el �ujo de ejecución de un programa. Esta

vista es accesible desde la vista de desarrollo, y permite depurar tanto archivos de código

binario como de código ensamblador. Las acciones de control de la ejecución incluyen la

ejecución de una sola instrucción, la ejecución hasta llegar cierta dirección de memoria,

ejecución completa y pausa de la ejecución. Además permite con�gurar la frecuencia

de proceso de instrucciones del computador digital xenon, así como observar el tiempo

transcurrido en la ejecución del programa.

También contiene una representación del computador digital, junto con sus registros

y señales, así como el contenido de la memoria principal. Tras la ejecución de cada

instrucción, los registros del computador y los registros de memoria que han cambiado

se marcarán en azul. A su vez también se marcarán las señales de gobierno que el

computador ha usado en la ejecución de la instrucción.

El visor entorno a P centrará la visualización de la memoria entorno a la dirección

de la instrucción ejecutada tras su ejecución, mientras que el visor de la memoria de la

parte inferior solo cambiará de posición según el usuario lo elija.

Cuando el usuario hace click en un registro de la memoria principal en el visor de

memoria entorno a P, el registro P cambia a la dirección del registro clickeado, de forma

que esa será la próxima instrucción que se ejecutará.

En la �gura 48 se puede ver la vista de depuración en uso:

88

Page 100: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Figura 48: Vista de depuración

Figura 49: Barra de control de de la vista de depuración

La �gura 49 muestra la barra de control de de la vista de depuración. Las acciones

que se pueden realizar son:

Ejecutar Instrucción. Ejecuta la siguiente instrucción, que viene dada por el

valor del registro P.

Ejecutar Hasta... Mostrará un diálogo donde el programa pide al usuario la

dirección de memoria hasta la que el usuario quiere ejecutar el programa. Entonces

el programa se ejecutará hasta llegar a una instrucción de parada (ALT) o hasta

llegar a la dirección de memoria indicada.

Comenzar de nuevo. Reinicia tanto los registros del computador como la me-

moria principal.

Ejecutar todo. Ejecuta el programa desde la posición de memoria actual indi-

cada por el registro P hasta llegar a una instrucción ALT de parada.

89

Page 101: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Pausar. Pausa la ejecución del programa, en el caso de que el programa se esté

ejecutando.

Salir del modo depuración. Devuelve al usuario a la vista de desarrollo.

Salir. Accesible desde el menú Archivo>Salir. Cierra el programa.

Elegir base. Haciendo uso del menú, se llega a Vista>Base, desde donde se puede

elegir la base de representación de los registros del computador y de la memoria

principal. Las opciones son Binario, Decimal, y Hexadecimal.

Cambiar la frecuencia del reloj, haciendo uso del slider o deslizador horizontal.

También es importante notar que a la izquierda del deslizador de frecuencia se muestra el

tiempo de ejecución del programa, que se actualiza tras la ejecución de cada instrucción.

Desde la barra de menús, mostrada en la �gura 50, también se tiene acceso a todas las

acciones. Como se puede observar, muchas de las acciones cuentan con combinaciones

de teclas de acceso rápido.

Figura 50: Barra de menús de la vista de depuración

90

Page 102: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

8. Posibles ampliaciones

En este capítulo analizamos una serie de posibles ampliaciones del presente proyecto

que, si bien su implementación no entra dentro del ámbito del proyecto, si puede resultar

interesante a la hora de continuar con el trabajo del emulador. Las ampliaciones que se

proponen son:

Una interfaz grá�ca para plataformas móviles.

Una ampliación del juego de instrucciones del computador digital.

En lo que sigue se detallan las acciones que habrían de llevarse a cabo a la hora de

implementar dichas ampliaciones.

8.1. Interfaz grá�ca para plataformas móviles

El código java no funciona directamente en plataformas móviles, pues el bytecode

no es el mismo y la interfaz grá�ca tampoco. Para realizar una versión del emulador en

plataformas móviles como AndroidMednieks, Zigurd (2012), es necesario reimplementar

la interfaz grá�ca pero se puede reusar el código referente a la lectura de binarios,

compilación de código ensamblador y emulación del computador.

Es importante recalcar que de hecho la mayor parte del código corresponde a la in-

terfaz grá�ca, por ello una implementación del emulador del computador virtual Xenon

en otra plataforma, como Android, donde se tenga que rehacer desde cero la interfaz

grá�ca, no es trivial. El código del programa es reusable, ya que existe una clara sepa-

ración entre las clases que pertenecen a la interfaz grá�ca y aquellas que no pertenecen

a ella. De hecho, gracias a esa separación, la vista de emulación y la vista de depuración

usan la misma clase para emular la ejecución de instrucciones del computador virtual

xenon, y para pasar de código binario a código que pueda interpretar el computador

virtual xenon. Dicho de otro modo, la separación entre clases relativas a la interfaz

grá�ca y clases relativas al funcionamiento abstracto del computador permite que el

código sea reusable, sin embargo es inevitable que la parte de la interfaz grá�ca tenga

que reescribirse al usarse otra librería grá�ca.

Las clases que si se pueden reusar son aquellas independientes de la interfaz grá�ca,

relativas al funcionamiento abstracto del computador digital Xenon:

Instruction. Esta clase de�ne una instrucción y unos métodos útiles para mane-

jarla. No necesitaría ninguna modi�cación.

91

Page 103: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

XenonHelper. Esta clase de�ne una serie de métodos que sirven para convertir un

texto en instrucciones que pueda entender el emulador, es decir compilar; y para

guardar y leer un archivo de código binario del computador. Los métodos save-

ToBinaryFile() y openBinaryFile() es posible que necesiten alguna modi�cación,

pues acceder al sistema de �cheros y leer o guardar un archivo es posible que no

se realice de la forma estándar en plataformas como un móvil Android. Todos los

demás métodos de esta clase son reusables tal cual.

VirtualComputer. Esta clase contiene los registros del computador digital y su

memoria principal y es la que se encarga de ejecutar instrucciones y modi�car los

registros, memoria y señales de gobierno que sea necesario para ello. Esta clase

tampoco hace falta que sea modi�cada, es independiente de la interfaz grá�ca.

Todas las demás clases del programa son totalmente dependientes de la interfaz grá�ca

y habrán de ser reimplementadas desde cero haciendo uso de las librerías de interfaz

grá�ca de Android. Será necesario por tanto reimplementar las tres vistas: emulación,

depuración y desarrollo.

A continuación sigue una breve introducción para el uso de las clases anteriormente

mencionadas de forma que se pueda implementar una nueva interfaz grá�ca. En los

siguientes ejemplos haremos un uso básico de las clases Instruction, XenonHelper y

VirtualComputer, que son las clases reusables e independientes de la interfaz grá�ca.

Es decir, una interfaz grá�ca para Android hará un uso de estas clases similar al que se

muestra en los siguientes ejemplos.

Supongamos que tenemos una cadena de texto correspondiente al código ensambla-

dor, en una variable de tipo String. El contenido de dicha cadna de texto podría ser

algo tan sencillo como �ORG 0\n ALT\n FIN�. En el ejemplo de la �gura 51 queremos

convertir la cadena de texto a un conjunto de instrucciones que el computador virtual

de VirtualComputer pueda entender.

92

Page 104: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

St r ing codigo_ensamblador ;...ArrayList<In s t ruc t i on> program_instruct ions = null ;try

{program_instruct ions = XenonHelper . t r an s l a t eTo In s t r u c t i on s ( t ex t ) ;

}catch ( Exception ce ){

System . out . p r i n t l n ( ce . getMessage ( ) ) ;}

Figura 51: Traducción de texto a instrucciones ensamblador

Una vez tenemos el programa almacenado como un conjunto de instrucciones en la

variable program_instructions, una instancia del computador virtual puede ejecutar di-

cho programa. Es importante añadir un listener al computador virtual para poder estar

al tanto de los cambios de los registros y señales del computador. En este caso la clase

principal implementará el listener. En este ejemplo solo ejecutamos una instrucción. El

computador inicialmente tendrá el puntero P a cero, luego ejecutaremos la instrucción

que esté en la posición de memoria cero. La �gura 52 muestra el código necesario para

ejecutar una instrucción.

93

Page 105: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

class Program implements VirtualComputer . VirtualComputerListener {public VirtualComputer computer ;public Program( ArrayList<In s t ruc t i on> program_instruct ions ){

computer = new VirtualComputer ( ) ;computer . s e t L i s t e n e r ( this ) ;// In i c i a l i z amo s l a memoria d e l computadorcomputer . setMemoryMap( codeArray ) ;//Ejecutamos una in s t r u c c i ón .computer . executeNext In s t ruc t i on ( ) ;

}//Métodos de Vir tua lComputerLis tener@Overridepublic void writeNumberToScreen ( ){}@Overridepublic void stateChanged ( ){}@Overridepublic void memoryChanged ( I n s t r u c t i o n i ){}@Overridepublic void writeCharacterToScreen ( ){}

}

Figura 52: Ejecución de una instrucción

Se puede observar que hemos incluido las implementaciones de la interfaz Virtual-

ComputerListener, si bien dichas implementaciones no hacen nada. Para poder realizar

una interfaz que sea capaz de manejar el computador virtual Xenon, habremos de im-

plementar los métodos de dicha interfaz. Por ejemplo, writeCharacterToScreen() será

llamado cuando el computador quiera mostrar un carácter en pantalla. Y memoryChan-

ged() será llamado cuando durante la ejecución de una instrucción, se modi�que una

posición de memoria. A su vez el computador llamará a stateChanged() tras la ejecución

de una instrucción, de modo que la interfaz pueda hacer uso del método VirtualCompu-

ter::getState() y comprobar qué registros y señales se han usado o activado durante la

ejecución de dicha instrucción. Para un ejemplo sencillo pero más completo de interfaz

grá�ca, ver el código del emulador, en el archivo fuente Emulator.java. En el código, en

94

Page 106: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

la de�nición de cada método se puede encontrar una explicación más detallada de la

funcionalidad y características de cada método.

8.2. Ampliación del juego de instrucciones del computador

El computador digital que aquí se ha presentado tiene instrucciones con un ancho

de 16 bits, y una capacidad de direccionamiento de 11 bits. Esto deja 5 bits para elegir

el código de operación (y modo de direccionamiento) de cada instrucción, lo cual como

mucho da para 32 instrucciones diferentes, las cuales todas menos una ya han sido

usadas. Y sin embargo existen todavía muchos tipos de operaciones que se podrían

de�nir para el computador. Para ello sería necesario o bien aumentar el tamaño de

la instrucción, es decir la cantidad de bits por instrucción; o disminuir la capacidad

de direccionamiento, sin embargo la capacidad de direccionamiento no es muy grande

ahora mismo. Por tanto la opción preferible es aumentar el tamaño de la instrucción.

De forma general, los cambios en el código del programa que habría que realizar

para añadir operaciones al computador virtual Xenon aumentando el tamaño de la

instrucción son:

Añadir los códigos de operación a la enumeración de códigos de operación. Tam-

bién será necesario cambiar la constante que de�ne el número máximo de código

de operación.

Modi�car aquellas partes del código que hagan uso de las instrucciones. Por ejem-

plo, habrá que añadir el comportamiento de las nuevas instrucciones en la clase

VirtualComputer en el método que ejecuta una instrucción.

Modi�car aquellas partes del código que hacen uso del tamaño de las instrucciones.

Por ejemplo, los registros del computador así como los registros de la memoria

principal pasarán a tener otro tamaño. A su vez, la clase Instruction hace uso del

tamaño de una instrucción para interpretar correctamente un dato en formato

decimal y pasarlo a binario o viceversa.

Modi�car aquellas partes del código que escriben o leen e interpretan código

binario. Ahora mismo una instrucción, o un registro de la memoria principal,

tiene el tamaño de 2 bytes. Si se añade 1 byte mas, hará falta modi�car por

ejemplo la clase XenonHelper, que guarda e interpreta archivos binarios.

95

Page 107: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

De forma más concreta, si por ejemplo queremos que la capacidad de direccionamiento

sea de 16 bits y que 8 bits pertenezcan al código de operación (incluyendo modo de

direccionamiento), esto permitiría 28 = 256 operaciones diferentes y una capacidad de

direccionamiento de 216 = 65536 direcciones de memoria diferentes, de forma que cada

instrucción contara con 16+8 = 24 bits = 3 bytes.

Los primeros cambios a realizar serán en la clase Instruction, referentes a las cons-

tantes se pueden ver en la �gura 53.

public stat ic f ina l int Memory_Address_Limit = 65535 ;public stat ic f ina l int Instruct ion_Size_Limit = 16777215;public stat ic f ina l int Register_Max_Limit = 8388607;public stat ic f ina l int Register_Min_Limit = −8388608;public stat ic f ina l int Operation_Code_Max = 255 ;

Figura 53: Cambios de constantes de la Clase Instruction

También será necesario añadir los códigos de operación a la enumeración de códigos

de operación, como se muestra en la �gura 54.

public enum OperationCode {ALT(0 , 0 ) , ALM(1 , 2) , ALMI(2 , 3 ) , CAR(3 , 4 ) , CARI(4 , 5 ) , ESC(5 , 6 ) ,ESCI (6 , 7 ) , LEE(7 , 8 ) , LEEI (8 , 9 ) , SUM(9 , 10) , SUMI(10 , 11) ,RES(11 , 12) , RESI (12 , 13) , MUL(13 , 14) , MULI(14 , 15) , DIV(15 , 16) ,DIVI (16 , 17) , MOD(17 , 18) , MODI(18 , 19) , SAL(19 , 20) ,SALI (20 , 21) , SAN(21 , 22) , SANI(22 , 23) , SAC(23 , 24) ,SACI(24 , 25) , SAP(25 , 26) , SAPI (26 , 27) , ECA(27 , 28) , ECAI(28 , 29) ,LCA(29 , 30) , LCAI(30 , 31) ,//Nuevos cód i gos de operación :OP32(31 ,32 ) , OP33(32 , 33) , OP34(33 , 34);

Figura 54: Cambios en la enumeración OperationCode

La clase Instruction, como se ha explicado en la sección 6.2.11, permite almacenar

una instrucción en un objeto java. Internamente, un objeto Instruction almacena la

instrucción tanto en forma binaria como en forma simbólica (código de operación y

operador). A la hora de actualizar la instrucción que contiene una variable Instruction,

existe tanto la opción de pasar la nueva instrucción en forma binaria como la opción de

pasar el código de operación y el operador.

96

Page 108: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Si por ejemplo realizamos una llamada a Instruction::setInstruction(OperationCode

oc, int operator), estaremos actualizando la instrucción a partir del código de opera-

ción y el operador de forma simbólica, sin embargo internamente la instrucción también

ha de ser guardada en formato binario. Para ello, internamente, el método setInstruc-

tion(OperationCode oc, int operator), hará una llamada a updateFromInstruction().

Del mismo modo, podremos actualizar la instrucción a partir del número en formato

binario (en realidad en complemento a 2) que se almacenaría en la memoria del compu-

tador, realizando una llamada a Instruction::setInstructionOperator(int operator). De

nuevo, internamente la instrucción también ha de ser guardada en formato simbólico

separando el código de operación y el operador. Para ello, internamente, el método

Instruction::setInstructionOperator(int operator) realizará una llamada a updateFrom-

Data().

El método updateFromData() devuelve el operador y el operando a partir del dato

de la instrucción (que se guarda en decimal en complemento a 2). Este método es depen-

diente del tamaño de la instrucción y del código de operación y del direccionamiento,

luego habría que modi�carlo tal y como se muestra en la �gura 55:

También es necesario hacer cambios en el método updateFromInstruction(), que

actualiza el dato en complemento a 2 a partir del operador y código de operación. Ese

método también depende del formato de un registro de memoria. Dichos cambios se

muestran en la �gura 56.

97

Page 109: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

private void updateFromData ( ){

int code = ( data & 0xFF0000 ) >> 16 ;i f ( code >= 0 && code <= Operation_Code_Max){

int i = −1;for ( OperationCode getIndex : OperationCode . va lue s ( ) ){

i f ( code == getIndex . code ( ) ){

i = getIndex . index ( ) ;break ;

}}i f ( i != −1){

operationCode = OperationCode . va lue s ( ) [ i ] ;insOperator = ( data & 0xFFFF) ;i s I n s t r u c t i o n = true ;

}else

{i s I n s t r u c t i o n = fa l se ;

}}else

{i s I n s t r u c t i o n = fa l se ;

}}

Figura 55: Cambios en Instruction::updateFromData()

98

Page 110: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

private void updateFromInstruct ion ( ){

int f oo = 0 ;i f ( i s I n s t r u c t i o n ( ) ){

foo = ( operationCode . code ( ) << 16) | insOperator ;}else

{i f ( operationCode == null && insOperator != −1){

foo = insOperator ;}else i f ( operationCode != null&& insOperator == −1){

foo = operationCode . code ( ) << 16 ;}

}try{

s e t In s t ruc t i onUns i gned ( foo ) ;}catch ( Exception e ){}

}

Figura 56: Cambios en Instruction::updateFromInstruction()

Serían necesarios cambios en la clase VirtualComputer. En el método que ejecuta

la siguiente instrucción, habría que añadir el código que ejecuta las nuevas instruccio-

nes, es decir, que modi�ca registros y hace uso de las señales de gobierno. Como se

puede ver en la �gura 57, hay que modi�car los registros necesarios, e indicar al estado

del computador aquellos registros y señales que se han usado para la ejecución de la

instrucción:

99

Page 111: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

public ComputerState executeNext In s t ruc t i on ( ) throws Exception {//Usamos e l semáforo t r a f f i c L i g h t para que no se puedan r e a l i z a r// l lamadas en pa r a l e l o / concurrentes a e s t a i n s t r u c c i ón .i f ( t r a f f i c L i g h t == fa l se ) {

t r a f f i c L i g h t = true ;//Recogemos l a i n s t r u c c i ón a e j e c u t a rI n s t r u c t i o n i n s = memoryMap [ s t a t e . getP ( ) ] ;//Marcamos todos l o s r e g i s t r o s y s eña l e s como no modi f i cadoss t a t e . r e s e t S i g n a l sR e g i s t e r s ( ) ;i f ( i n s . i s I n s t r u c t i o n ( ) == true ){

switch ( i n s . getOperationCode ( ) ) //Elegimos qué operación e j e cu t a r// según e l cód igo de operación .

{case ALT:

break ;...//Nuevas i n s t r u c c i on e scase OP32 :

try{int operator = in s . g e t In s t ruc t i onOpera to r ( ) ;memoryMap [ operator ] . s e t I n s t r u c t i onS i gn ed ( s t a t e . getA ( ) ) ;s t a t e . g e tL i s t en e r ( ) . memoryChanged (memoryMap [ operator ] ) ;s t a t e . setChangedMemory (

memoryMap [ operator ] . getAddressLocat ion ( ) ) ;s t a t e . setT ( s t a t e . getA ( ) ) ;s t a t e . s e t I ( i n s . getDataSigned ( ) ) ;s t a t e . se tS ( operator ) ;s t a t e . incrementP ( ) ;//Ahora señalamos qué r e g i s t r o s han cambiados t a t e . setRegisterChanged ( ComputerRegister .T, true ) ;s t a t e . setRegisterChanged ( ComputerRegister . I , true ) ;s t a t e . setRegisterChanged ( ComputerRegister . S , true ) ;s t a t e . setRegisterChanged ( ComputerRegister .P, true ) ;//Aquí mostramos l a s s eña l e s usadas en e l t ranscurso de l a// e j e cuc ión de l a i n s t r u c c i ón .//Algunos s e t S i g n a l l o s comento , pero s o l o para no// r e p e t i r l lamadas i g u a l e s//M(P) −> Is t a t e . s e t S i g n a l ( ComputerSignal . SP , true ) ;s t a t e . s e t S i g n a l ( ComputerSignal .ES , true ) ;s t a t e . s e t S i g n a l ( ComputerSignal .LECM, true ) ;s t a t e . s e t S i g n a l ( ComputerSignal . ST, true ) ;

Figura 57: Cambios en VirtualComputer::executeNextInstruction()

100

Page 112: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

s t a t e . s e t S i g n a l ( ComputerSignal . EI , true ) ;//A −> M(D)

s t a t e . s e t S i g n a l ( ComputerSignal .SD, true ) ;// s t a t e . s e t S i g n a l ( ComputerSignal .ES , t rue ) ;s t a t e . s e t S i g n a l ( ComputerSignal . SA, true ) ;s t a t e . s e t S i g n a l ( ComputerSignal .ET, true ) ;s t a t e . s e t S i g n a l ( ComputerSignal .ESCM, true ) ;//P −> P+1s t a t e . s e t S i g n a l ( ComputerSignal . INCP, true ) ;s t a t e . s endS igna l s ( ) ;

}catch ( IndexOutOfBoundsException except ion ){

throw new Exception ( "ALM" ) ;}break ;

case OP33 : . . .

Figura 58: Cambios en VirtualComputer::executeNextInstruction() (continuación)

La clase XenonHelper necesitará cambios. Por ejemplo, a la hora de leer o escribir

un archivo de código binario ahora una instrucción no ocupa dos sino tres bytes. Por

ello habrá que modi�car translateToBinary() tal y como se puede observar en la �gura

59:

public stat ic byte [ ] t rans lateToBinary ( ArrayList<In s t ruc t i on> code ){

byte [ ] b inary = new byte [ ( I n s t r u c t i o n . Memory_Address_Limit+1)*3 ] ;int f oo = 0 ;for ( I n s t r u c t i o n i : code ){

foo = i . getDataUnsigned ( ) ;//BigEndian or L i t t l eEnd ian ?binary [ i . getAddressLocat ion ( ) * 3 ] = intToByte ( foo & 0x0000FF ) ;b inary [ i . getAddressLocat ion ( )*3 + 1 ] =

intToByte ( ( foo & 0x00FF00 ) >> 8 ) ;b inary [ i . getAddressLocat ion ( )*3 + 2 ] =

intToByte ( ( foo & 0x00FF00 ) >> 16 ) ;}return binary ;

}

Figura 59: Cambios en XenonHelper::translateToBinary()

101

Page 113: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

De igual modo también será necesario modi�car translateFromBinary() para tener

en cuenta el mayor tamaño de cada instrucción, según se muestra en el código de la

�gura 60:

public stat ic ArrayList<In s t ruc t i on> trans lateFromBinary (byte [ ] b inary ){

ArrayList<In s t ruc t i on> array = new ArrayList<In s t ruc t i on >() ;int f oo = 0 ;I n s t r u c t i o n s r ;for ( int i = 0 ; i < binary . l ength /3 ; i++){

foo= byteToInt ( binary [ i *3 ] ) + ( byteToInt ( binary [ i *3 + 1 ] ) << 8)+ ( byteToInt ( binary [ i *3 + 2 ] ) << 16 ) ;i f ( foo != 0){

s r = new I n s t r u c t i o n ( ) ;try{

s r . s e t In s t ruc t i onUns i gned ( foo ) ;s r . se tAddressLocat ion ( i ) ;

}catch ( Exception e ){}array . add ( s r ) ;

}}return array ;

}

Figura 60: Cambios en XenonHelper::translateFromBinary()

102

Page 114: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

9. Conclusiones y cumplimiento de objetivos

En este Proyecto Fin de Carrera se ha estudiado un computador digital, creando un

emulador y un entorno de programación simple llamado Xenon que permite el uso de

dicho computador. El programa Xenon permite escribir, compilar, ejecutar y depurar

código ensamblador del computador digital diseñado. Se ha utilizado el lenguaje de

programación Java para la programación del emulador Xenon, ya que un ejecutable

Java se puede ejecutar sin cambio alguno en múltiples plataformas, sin que se concurra

en una gran pérdida de rendimiento.

Se han propuesto dos ampliaciones:

La implementación del programa Xenon para plataformas móviles, como por ejem-

plo Android. Para ello, sería necesario escribir una nueva interfaz grá�ca.

Ampliación de las instrucciones que maneja el computador digital. Para ello sería

necesario realizar modi�caciones tanto en la parte de la interfaz grá�ca como la

parte del código relativa al emulador.

En cuanto a los objetivos del proyecto, se puede decir que:

El diseño de la computadora simple se ha cumplido con el presente documento. El

desarrollo del software que permite emular dicho computador, también se ha rea-

lizado satisfactoriamente, incluyendo un entorno de programación, un depurador

y un emulador.

En el presente documento se han detallado dos posibles ampliaciones de este

proyecto.

Gracias a una implementación del emulador Xenon en Java, el emulador puede

ser ejecutado tanto en Windows como Mac y Linux sin necesidad de recompilar

el programa.

El software Xenon se usará en el próximo curso para introducir al alumnado el

funcionamiento de un computador digital simple. El entorno de programación y el

emulador permitirán a los alumnos experimentar con el computador como si éste

fuera una realidad física. A su vez, el depurador muestra el funcionamiento interno

del computador, con detalles como qué registros y señales usa cada instrucción

en cada ciclo, y mostrando al alumno el contenido de dichos registros y de la

memoria del computador.

103

Page 115: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Por tanto se concluye que todos los objetivos del proyecto se han cumplido.

104

Page 116: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

10. Bibliografía

Referencias

Acosta Rodriguez, José Ángel (2009). Asignatura de informática de ingeniería aeroes-

pacial. http://www.esi2.us.es/ jaar/docencia.htm.

Arahal, Manuel R; Hernández, José Julio; Limón, Daniel (1986). CESIUS.

http://www.esi2.us.es/ arahal/CESIUS/cesius.html.

Boole, George (1854). An Investigation of the Laws of Thought on Which are Founded

the Mathematical Theories of Logic and Probabilities. Macmillan.

Gite, Vivek (1999). Linux Shell Scripting Tutorial. http://bash.cyberciti.biz/guide/.

Lapitsky, Stanislav (2007). Jconnector project. http://java-sl.com/connector.html.

Mednieks, Zigurd (2012). Programming Android: Java Programming for the New Ge-

neration of Mobile Devices. O'Reilly Media.

Shannon, Claude E. (1937). A symbolic analysis of relay and switching circuits. Master's

thesis, Massachusetts Institute of Technology.

Shannon, Claude E. (1948). A mathematical theory of communication. Bell System

Technical Journal, -:�.

van Heesch, Dimitri (1997). Announcing: the �rst release of doxygen. -.

Varios (2013). Tortoisehg webpage. http://tortoisehg.bitbucket.org/.

von Neumann, John (1945). First draft of a report on the edvac. Technical report,

United States Army Ordenance Department and the University of Pennsylvania.

105

Page 117: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

106

Page 118: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11 Anexos

11.1 Código

11.1.1 ButtonTabComponent.java package xenon;

import javax.swing.*;import javax.swing.plaf.basic.BasicButtonUI;import java.awt.*;import java.awt.event.*;

/** * @brief Usado como tabComponent * @detail Contiene una JLabel para mostrar el texto y un JButton para * cerrar la pestaña a la que pertenece. */ public class ButtonTabComponent extends JPanel {

/** * */private static final long serialVersionUID = 1L;

@SuppressWarnings("unused")private TabsManager manager;

private JLabel label; public JLabel getLabel() { return label; }

public ButtonTabComponent(TabsManager manager, String Name) { super(new FlowLayout(FlowLayout.LEFT, 0, 0)); if (manager.getTabbedPane() == null) { throw new NullPointerException("TabbedPane is null"); } this.manager = manager; setOpaque(false); //Hacer que la JLabel muestre los títulos del JTabbedPane label = new JLabel(Name); add(label); //Añadir más espacio entre la etiqueta y el botón label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); //Botón de la pestaña JButton button = new TabButton(manager); add(button); //Añadir más espacio a la parte superior del componente setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); }

/** * * @brief Crea botón con X para cerrar pestaña. * */ private class TabButton extends JButton implements ActionListener { /**

* */private static final long serialVersionUID = 1L;private TabsManager manager;

public TabButton(TabsManager manager) { this.manager = manager; int size = 17; setPreferredSize(new Dimension(size, size)); setToolTipText("Cerrar esta pestaña"); setUI(new BasicButtonUI()); //Hacerlo transparente setContentAreaFilled(false); //No necesitamos que se pueda enfocar setFocusable(false); setBorder(BorderFactory.createEtchedBorder()); setBorderPainted(false); //Usamos el mismo listener para todos los botones addMouseListener(buttonMouseListener); setRolloverEnabled(true); //Cerrar la pestaña adecuada al hacer click en el botón addActionListener(this); }

107

Page 119: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

public void actionPerformed(ActionEvent e) { manager.getTabbedPane().indexOfTabComponent(ButtonTabComponent.this); manager.removeTab(ButtonTabComponent.this); }

//No necesitamos actualizar la UI en este caso public void updateUI() { }

//Pintar la cruz protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g.create(); //Mover la imagen si se presiona if (getModel().isPressed()) { g2.translate(1, 1); } g2.setStroke(new BasicStroke(2)); g2.setColor(Color.BLACK); if (getModel().isRollover()) { g2.setColor(Color.MAGENTA); } int delta = 6; g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1); g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1); g2.dispose(); } }

private final static MouseListener buttonMouseListener = new MouseAdapter() { public void mouseEntered(MouseEvent e) { Component component = e.getComponent(); if (component instanceof AbstractButton) { AbstractButton button = (AbstractButton) component; button.setBorderPainted(true); } }

public void mouseExited(MouseEvent e) { Component component = e.getComponent(); if (component instanceof AbstractButton) { AbstractButton button = (AbstractButton) component; button.setBorderPainted(false); } } };}

108

Page 120: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.2 JConnector.java package xenon;

import javax.swing.*;import java.awt.*;

/** * The class represents pair of components with a connecting line. * * <p>Copyright: Copyright (c) 2007</p> * * @author Stanislav Lapitsky * @version 1.0 */

/** * @brief Una de las clases usada para pintar flechitas de un lado a otro * @detail Librería modificada por Félix Robles, código original de Stanislav Lapitsky. */ public class JConnector extends JPanel { /**

* */private static final long serialVersionUID = 1L;public static final int CONNECT_LINE_TYPE_SIMPLE = 0;

public static final int CONNECT_LINE_TYPE_RECTANGULAR = 1; protected JComponent source; protected JComponent dest; protected ConnectLine line; protected int lineArrow = ConnectLine.LINE_ARROW_NONE; protected int lineType = CONNECT_LINE_TYPE_RECTANGULAR; protected Color lineColor;

/** * Constructs default connector. * @param source JComponent * @param dest JComponent */ public JConnector(JComponent source, JComponent dest) { this(source, dest, ConnectLine.LINE_ARROW_NONE, Color.BLACK); }

/** * Constructs a connector with specified arrow and color. * @param source JComponent * @param dest JComponent * @param lineArrow int * @param lineColor Color */ public JConnector(JComponent source, JComponent dest, int lineArrow, Color lineColor) { this(source, dest, lineArrow, CONNECT_LINE_TYPE_RECTANGULAR, lineColor); }

/** * Constructs a connector with specified arrow, line type and color. * @param source JComponent * @param dest JComponent * @param lineArrow int * @param lineType int * @param lineColor Color */ public JConnector(JComponent source, JComponent dest, int lineArrow, int lineType, Color lineColor) { this.source = source; this.dest = dest; this.lineArrow = lineArrow; this.lineType = lineType; this.lineColor = lineColor; }

/** * Overrides parent's paint(). It resets clip to draw connecting line * between components and set the clip back. * @param g Graphics */ public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; calculateLine(); if (line != null) { Shape oldClip = g2d.getClip(); g2d.setClip(getLineBounds()); g2d.setColor(lineColor); line.paint(g2d); g2d.setClip(oldClip); } }

protected void calculateLine() { Rectangle rSource = source.getBounds();

109

Page 121: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

Rectangle rDest = dest.getBounds(); if (rSource.intersects(rDest)) { line = null; return; }

boolean xIntersect = (rSource.x <= rDest.x && rSource.x + rSource.width >= rDest.x) || (rDest.x <= rSource.x && rDest.x + rDest.width >= rSource.x); boolean yIntersect = rSource.y <= rDest.y && rSource.y + rSource.height >= rDest.y || (rDest.y <= rSource.y && rDest.y + rDest.height >= rSource.y);

if (xIntersect) { int y1; int y2; int x1 = rSource.x + rSource.width / 2; int x2 = rDest.x + rDest.width / 2; if (rSource.y + rSource.height <= rDest.y) { //source higher y1 = rSource.y + rSource.height; y2 = rDest.y; } else { y1 = rSource.y; y2 = rDest.y + rDest.height; } line = new ConnectLine(new Point(x1, y1), new Point(x2, y2), ConnectLine.LINE_TYPE_RECT_VERTICAL, ConnectLine.LINE_START_VERTICAL, lineArrow); if (lineType == CONNECT_LINE_TYPE_SIMPLE) { line.setLineType(ConnectLine.LINE_TYPE_SIMPLE); } } else if (yIntersect) {

int y1 = rSource.y + rSource.height / 2; ; int y2 = rDest.y + rDest.height / 2; ; int x1; int x2; if (rSource.x + rSource.width <= rDest.x) { x1 = rSource.x + rSource.width; x2 = rDest.x; } else { x1 = rSource.x; x2 = rDest.x + rDest.width; } line = new ConnectLine(new Point(x1, y1), new Point(x2, y2), ConnectLine.LINE_TYPE_RECT_HORIZONTAL, ConnectLine.LINE_START_HORIZONTAL, lineArrow); if (lineType == CONNECT_LINE_TYPE_SIMPLE) { line.setLineType(ConnectLine.LINE_TYPE_SIMPLE); } } else { int y1; int y2; int x1; int x2; if (rSource.y + rSource.height <= rDest.y) { //source higher y1 = rSource.y + rSource.height / 2; y2 = rDest.y; if (rSource.x + rSource.width <= rDest.x) { x1 = rSource.x + rSource.width; } else { x1 = rSource.x; } x2 = rDest.x + rDest.width / 2; } else { y1 = rSource.y + rSource.height / 2; y2 = rDest.y + rDest.height; if (rSource.x + rSource.width <= rDest.x) { x1 = rSource.x + rSource.width; } else { x1 = rSource.x; } x2 = rDest.x + rDest.width / 2; } line = new ConnectLine(new Point(x1, y1), new Point(x2, y2), ConnectLine.LINE_TYPE_RECT_1BREAK, ConnectLine.LINE_START_HORIZONTAL, lineArrow); if (lineType == CONNECT_LINE_TYPE_SIMPLE) { line.setLineType(ConnectLine.LINE_TYPE_SIMPLE); } } }

protected Rectangle getLineBounds() { int add = 10; int maxX = Math.max(line.getP1().x, line.getP2().x);

110

Page 122: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

int minX = Math.min(line.getP1().x, line.getP2().x); int maxY = Math.max(line.getP1().y, line.getP2().y); int minY = Math.min(line.getP1().y, line.getP2().y);

Rectangle res = new Rectangle(minX - add, minY - add, maxX - minX + 2 * add, maxY - minY + 2 * add); return res; }

public Color getLineColor() { return lineColor; }

public void setLineColor(Color c) { lineColor = c; }

public int getLineType() { return lineType; }

public void setLineType(int type) { lineType = type; }

public int getLineArrow() { return lineArrow; }

public void setLineArrow(int arrow) { lineArrow = arrow; } }

111

Page 123: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.3 Emulator.java

package xenon;

import java.awt.Container;import java.awt.EventQueue;import java.awt.event.ActionEvent;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.event.MouseListener;import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.util.ArrayList;import java.util.Timer;import java.util.TimerTask;

import javax.swing.AbstractAction;import javax.swing.Action;import javax.swing.GroupLayout;import javax.swing.GroupLayout.Alignment;import javax.swing.filechooser.FileFilter;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JFileChooser;import javax.swing.JFrame;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JPanel;import javax.swing.JPopupMenu;import javax.swing.JScrollPane;import javax.swing.JTextPane;import javax.swing.JToolBar;import javax.swing.KeyStroke;

import xenon.DebugViewManager.InputType;import xenon.Instruction.OperationCode;

/** * @brief Clase gestora de la vista de emulación. * @detail Esta clase realiza todas las tareas de la interfaz gráfica de la vista de emulación, * además de lidiar con la clase VirtualComputer. */ public class Emulator extends JFrame implements VirtualComputer.VirtualComputerListener {

private static final long serialVersionUID = 1L;private JTextPane consoleArea; //Consola de entrada y salida de datos//Buffer de entrada. Se van añadiendo datos hasta recibir un enter (en el caso de que el computador esté pidiendo datos)private String inputBuffer; //Timer usado para organizar la

ejecución de instrucciones.private VirtualComputer computer; //Instancia del computador que se está emulandoprivate ConsoleKeyListener consolaListener; //Listener que recoge y trata la entrada proveniente del

teclado//Si el simulador se está ejecutando en forma standalone, cerrar la ventana cerrará todo//el programa, en ese caso esta variable valdrá true.

private boolean exitOnClose;Timer timer;ExecuteInstructionTask task; //Tarea de ejecución de una instrucción.private long period; //Período de reloj de una instrucción del computador en milisegundos = 1000/f

/** * @brief Tarea que ejecuta una instrucción. * @detail El timer instructionTimer llamará a la función run() una vez por el período de tiempo fijado. * Esa función se encarga de ejecutar la siguiente instrucción. */

class ExecuteInstructionTask extends TimerTask{

@Overridepublic void run() {

if(consolaListener.getPidiendoDatos() == InputType.FALSE){

actionExecuteNextInstruction();}

}public void stop(){

this.cancel();}

} /** * * @brief Sirve de filtro para mostrar solo los ficheros con la extensión binaria "ece". * */

112

Page 124: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

public class BinaryFilter extends FileFilter {

//Aceptar todos los directorios y los ficheros .ece (binarios) public boolean accept(File f) { if (f.isDirectory()) { return true; }

String arg1 = f.getName().toLowerCase(); if(arg1.lastIndexOf('.')>0) { // get last index for '.' char int lastIndex = arg1.lastIndexOf('.'); // get extension String extension = arg1.substring(lastIndex); if (extension != null) { if (extension.equals(".ece") ) { return true; } } }

return false; }

//Descripción de este filtro public String getDescription() { return "Binarios"; } }

/** * @brief Clase que escucha la entrada del teclado y la representa en la consola. * @detail Cuando el usuario presione ENTER, los datos se mandarán al computador. */

class ConsoleKeyListener implements KeyListener{

private InputType inputAsked;

/** * Informa al listener de si el computador está pidiendo datos. * @param b Define si el computador está pidiendo datos, y de qué tipo */public void setPidiendoDatos(InputType b){

inputAsked = b;if(inputAsked != InputType.FALSE){

consoleArea.requestFocus();if(inputAsked == InputType.CARACTER){

consoleArea.setText(consoleArea.getText() + "\nIntroduzca un carácter: ");

}else if(inputAsked == InputType.NUMBER){

consoleArea.setText(consoleArea.getText() + "\nIntroduzca un número: ");

}}

}

/** * @brief Informa de si actualmente el computador está a la espera de datos de entrada. */public InputType getPidiendoDatos(){

return inputAsked;}

void displayInfo(KeyEvent e){

if(inputAsked != InputType.FALSE){

String s = consoleArea.getText();int id = e.getID();if (id == KeyEvent.KEY_TYPED) {

s += e.getKeyChar(); }

consoleArea.setText(s);if(inputBuffer == null){

inputBuffer = new String("");}if(KeyEvent.VK_ENTER == e.getKeyChar()){

String in = getConsoleInput();if(in == null) //Se ha pulsado enter pero no se han introducido datos{

try{

113

Page 125: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

computer.getState().setE(0);}

catch (Exception x){

}}else{

if(inputAsked == InputType.NUMBER) //El dato pedido es un número{

try{int inn = Integer.parseInt(in);try{

computer.getState().setE(inn);}catch (Exception xx){

//TODO:}

}catch (NumberFormatException nfe) {

//TODO:}

}else if(inputAsked == InputType.CARACTER) //El dato pedido es un carácter{

if(in.length() == 1){

try{int inn =

(char)in.charAt(0);//Character.getNumericValue(in.charAt(0));try{

computer.getState().setE(inn);}catch (Exception xx){

//TODO:}

}catch (NumberFormatException nfe) {

//TODO:}}else{

//TODO: Error la cadena introducida es demasiado larga (debería ser 1 solo carácter).

}}

}try{

computer.executeNextInstruction();}catch(Exception excep){

}

setPidiendoDatos(InputType.FALSE);}else //Si no se ha pulsado ENTER, añadimos la entrada del teclado al buffer de entrada{

inputBuffer += e.getKeyChar();}

}}

@Overridepublic void keyPressed(KeyEvent e) {}

@Overridepublic void keyReleased(KeyEvent e) {}

//Esta función es llamada cada vez que se pulsa una tecla mientras la consola esté enfocada.@Overridepublic void keyTyped(KeyEvent e) {

// TODO Auto-generated method stubdisplayInfo(e);

}}

/** * @detail Devuelve los datos del buffer de entrada del teclado * @return */

114

Page 126: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

public String getConsoleInput(){

String r = null;if(inputBuffer != null){

r = new String(inputBuffer);}inputBuffer = null;return r;

}/** * Método main, es el método de entrada del programa, el primero que se ejecuta. * @param args */public static void main(String[] args) {

EventQueue.invokeLater(new Runnable() {public void run() {

try {Emulator frame = new Emulator();frame.pack();frame.setVisible(true);

} catch (Exception e) {e.printStackTrace();

}}

});}

/** * @brief Método que cambia el título de la ventana del emulador * @param s */public void setMyTitle(String s){

setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);exitOnClose = false;setTitle("Emulador CESIUS - " + s);

}/** * @brief Constructor que inicializa la clase */public Emulator(){

super();setBounds(100, 100, 800, 600);setTitle("Emulador CESIUS");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);exitOnClose = true;

consoleArea = null;inputBuffer = "";computer = new VirtualComputer();computer.setListener(this);timer = new Timer("Timer");task = null;//Período del reloj de la máquina en milisegundos.period = 50L;

addComponentToPane(getContentPane());

}

/** * Añade la cadena text a la consola * @param text */public void addConsoleOutput(String text){

String s = consoleArea.getText();s += text;consoleArea.setText(s);

}

/** * @detail Método que sirve para dar a conocer a la vista de depuración si * el computador está a la espera de datos. * @param b */public void setPidiendoDatos(InputType b){

consolaListener.setPidiendoDatos(b);}

/** * @detail Acción Ejecutar siguiente instrucción. Solo ejecuta una instrucción. */public void actionExecuteNextInstruction(){

//Check if next instruction needs some kind of input.OperationCode op = computer.getNextInstruction().getOperationCode();

115

Page 127: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

if(op == OperationCode.LCA || op == OperationCode.LCAI ){

/* * In that case the instruction will be executed when when we get the input. */

setPidiendoDatos(InputType.CARACTER);}else if(op == OperationCode.LEE || op == OperationCode.LEEI){

/* * In that case the instruction will be executed when when we get the input. */setPidiendoDatos(InputType.NUMBER);

}else{

//If it's not needed, execute instruction.if(op == OperationCode.ALT){

actionPause();}else{

try{computer.executeNextInstruction();

}catch(Exception e){

//TODO: Catch exception}

}}

}

/** * @detail Acción Pausar. Detiene la ejecución de instrucciones. */public void actionPause(){

if(task != null){

task.cancel();task = null;

}}

/** * @brief Inicializa la memoria del computador con cierto código * @param codeArray Código a ejecutar */public void setRunCode(ArrayList<Instruction> codeArray){

actionRestart();computer.setMemoryMap(codeArray);actionRun();

}

/** * @brief Acción Reiniciar. Reinicia el estado del computador. */public void actionRestart(){

if(task != null){

task.cancel();task = null;

}consoleArea.setText("");consolaListener.setPidiendoDatos(InputType.FALSE);try{

computer.restart();actionRun();

}catch(Exception e){

}}/** * @detail Acción "Ejecutar Todo". Ejecuta las instrucciones del ordenador hasta llegar a un ALT, * con la frecuencia del computador seleccionada. */public void actionRun(){

if(task == null){

consolaListener.setPidiendoDatos(InputType.FALSE);task = new ExecuteInstructionTask();

116

Page 128: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

timer.scheduleAtFixedRate(task, 0, period);}

}

@Overridepublic void writeNumberToScreen() {

addConsoleOutput("" + computer.getState().getE());}

@Overridepublic void stateChanged() {

}

@Overridepublic void memoryChanged(Instruction i) {

}

/** * @brief Añade todos los componentes visuales necesarios al panel. * @param pane */public void addComponentToPane(Container pane){

//A continuación definimos todas las acciones de la vista de emulaciónjava.net.URL imageURL = Interface.class.getResource("images/gtk-quit.png");ImageIcon icon = new ImageIcon(imageURL);Action actionSalir = new AbstractAction("Salir", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

if(exitOnClose){

//Cerrar todoSystem.exit(0);

}else {

//No cierra toda la aplicación, solo esta ventana.dispose();

} } };

imageURL = Interface.class.getResource("images/gnome-fs-directory.png");icon = new ImageIcon(imageURL);Action actionAbrirEjecutable = new AbstractAction("Abrir Ejecutable", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

JFileChooser SaveAs = new JFileChooser();

SaveAs.setFileFilter(new BinaryFilter());SaveAs.setAcceptAllFileFilterUsed(false);int actionDialog = SaveAs.showDialog(null, "Abrir");if(actionDialog == JFileChooser.APPROVE_OPTION){

String path = SaveAs.getSelectedFile().getPath();File fileName = new File(path);if (fileName != null){

ProjectFile codeToExecute = new ProjectFile(fileName,null);if(codeToExecute != null && codeToExecute.type ==

ProjectFile.FileType.BINARY){

try {

//CesiusHelper core = new CesiusHelper();ArrayList<Instruction> in =

XenonHelper.openBinaryFile(codeToExecute.file);setRunCode(in);System.out.println("Ejecutando binario: " +

codeToExecute.file.getName());setTitle("Emulador CESIUS - " +

codeToExecute.file.getPath());}catch(Exception x){

System.out.println(x.getMessage());}

}}

}

117

Page 129: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

} };

imageURL = Interface.class.getResource("images/document-save.png");icon = new ImageIcon(imageURL);Action actionGuardar = new AbstractAction("Guardar Texto de Consola", icon) {

/** * */

private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

JFileChooser SaveAs = new JFileChooser();int actionDialog = SaveAs.showDialog(null, "Guardar Como...");if(actionDialog == JFileChooser.APPROVE_OPTION){

String path = SaveAs.getSelectedFile().getPath();File fileName = new File(path);if (fileName != null){

System.out.println("Guardando " + path + " ...");try {

BufferedWriter outFile = new BufferedWriter(new FileWriter(fileName));

outFile.write(consoleArea.getText()); //put in textfile outFile.close();

}catch (IOException ex) {

}}

} } };

Action actionLimpiarProblemas = new AbstractAction("Limpiar", null) {/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

consoleArea.setText(""); } };

imageURL = Interface.class.getResource("images/reload.png");icon = new ImageIcon(imageURL);Action actionReiniciar = new AbstractAction("Reiniciar máquina", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

actionRestart();actionRun();

} };

//A continuación definimos la barra de menúsJMenuBar menuBar = new JMenuBar();JMenu menu;JMenuItem menuItem;menu = new JMenu("Archivo");menuBar.add(menu);

menuItem = menu.add(actionAbrirEjecutable);menu.add(menuItem);

menuItem = menu.add(actionGuardar);menu.add(menuItem);

menu = new JMenu("Emulador");menuBar.add(menu);

menuItem = menu.add(actionReiniciar);menu.add(menuItem);

menuItem = menu.add(actionSalir);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, ActionEvent.CTRL_MASK));menu.add(menuItem);

//A continuación, la barra de herramientas JToolBar toolBar;

toolBar = new JToolBar();toolBar.setFloatable(false);

118

Page 130: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

JButton button = toolBar.add(actionAbrirEjecutable);button.setToolTipText("Abrir Ejecutable");

button = toolBar.add(actionGuardar);button.setToolTipText("Guardar texto de la consola");

button = toolBar.add(actionReiniciar);button.setToolTipText("Reiniciar máquina");

//Iniciamos la consolaconsoleArea = new JTextPane();consoleArea.setEditable(false);//Con esto, el enter será sólo un carácter raro sin efectoconsoleArea.setFocusTraversalKeysEnabled(false);

consolaListener = new ConsoleKeyListener();consoleArea.addKeyListener(consolaListener);consolaListener.setPidiendoDatos(InputType.FALSE);

JScrollPane scrollPane = new JScrollPane(consoleArea);

JPanel codeJPanel = new JPanel();

//Añadimos el popup de limpiar consolaJPopupMenu popup = new JPopupMenu();popup.add(actionLimpiarProblemas);MouseListener popupListener = new PopupListener(popup);consoleArea.addMouseListener(popupListener);

//Aquí definimos la disposición gráfica de los componentes en la vista de emulación. GroupLayout gl_menu1 = new GroupLayout(codeJPanel); gl_menu1.setHorizontalGroup( gl_menu1.createParallelGroup(Alignment.LEADING) .addComponent(menuBar, 0, 800, Short.MAX_VALUE) .addComponent(toolBar, 0, 800, Short.MAX_VALUE) .addComponent(scrollPane, 0, 800, Short.MAX_VALUE) ); gl_menu1.setVerticalGroup( gl_menu1.createParallelGroup(Alignment.LEADING) .addGroup(gl_menu1.createSequentialGroup() .addComponent(menuBar, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(toolBar, GroupLayout.PREFERRED_SIZE, 24, GroupLayout.PREFERRED_SIZE) .addComponent(scrollPane, 0, 560, Short.MAX_VALUE) ) );

codeJPanel.setLayout(gl_menu1); pane.add(codeJPanel);

}

@Overridepublic void writeCharacterToScreen() {

// TODO Auto-generated method stubchar c = (char)computer.getState().getE();addConsoleOutput(Character.toString(c));

}}

119

Page 131: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.4 ConnectLine.java package xenon;import java.awt.*;import java.awt.geom.Point2D;

/** * The class represents base line model and rendering according to multiple params. * * <p>Copyright: Copyright (c) 2007</p> * * @author Stanislav Lapitsky * @version 1.0 */

/** * @brief Una de las clases usada para pintar flechitas de un lado a otro * @detail Librería modificada por Félix Robles, código original de Stanislav Lapitsky. */ public class ConnectLine { public static final int LINE_TYPE_SIMPLE = 0; public static final int LINE_TYPE_RECT_1BREAK = 1; public static final int LINE_TYPE_RECT_2BREAK = 2; public static final int LINE_TYPE_RECT_HORIZONTAL = 3; public static final int LINE_TYPE_RECT_VERTICAL = 4;

public static final int LINE_START_HORIZONTAL = 0; public static final int LINE_START_VERTICAL = 1;

public static final int LINE_ARROW_NONE = 0; public static final int LINE_ARROW_SOURCE = 1; public static final int LINE_ARROW_DEST = 2; public static final int LINE_ARROW_BOTH = 3;

public static int LINE_ARROW_WIDTH = 5;

/** * Source line point */ Point p1; /** * Destination line point */ Point p2;

/** * Line type can be one of LINE_TYPE_SIMPLE, LINE_TYPE_RECT_1BREAK, LINE_TYPE_RECT_2BREAK */ int lineType = LINE_TYPE_SIMPLE; /** * for the LINE_TYPE_RECT_2BREAK type the param defines how line should be rendered */ int lineStart = LINE_START_HORIZONTAL; /** * arrow can be one of following * LINE_ARROW_NONE - no arrow * LINE_ARROW_SOURCE - arrow beside source point * LINE_ARROW_DEST - arrow beside dest point * LINE_ARROW_BOTH - both source and dest has arrows */ int lineArrow = LINE_ARROW_NONE; /** * Constructs default line * @param p1 Point start * @param p2 Point end */ public ConnectLine(Point p1, Point p2) { this(p1, p2, LINE_TYPE_SIMPLE, LINE_START_HORIZONTAL, LINE_ARROW_NONE); }

/** * Constructs line with specified params * @param p1 Point start * @param p2 Point end * @param lineType int type of line (LINE_TYPE_SIMPLE, LINE_TYPE_RECT_1BREAK, LINE_TYPE_RECT_2BREAK) * @param lineStart int for the LINE_TYPE_RECT_2BREAK type the param defines how line should be rendered * @param lineArrow int defines line arrow type */ public ConnectLine(Point p1, Point p2, int lineType, int lineStart, int lineArrow) { this.p1 = p1; this.p2 = p2; this.lineType = lineType; this.lineStart = lineStart; this.lineArrow = lineArrow; }

/** * Paints the line with specified params * @param g2d Graphics2D */ public void paint(Graphics2D g2d) {

120

Page 132: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

switch (lineType) { case LINE_TYPE_SIMPLE: paintSimple(g2d); break; case LINE_TYPE_RECT_1BREAK: paint1Break(g2d); break; case LINE_TYPE_RECT_2BREAK: paint2Breaks(g2d); break; case LINE_TYPE_RECT_HORIZONTAL: paintHorizontal(g2d); break; case LINE_TYPE_RECT_VERTICAL: paintVertical(g2d); break; } } protected void paintVertical(Graphics2D g2d) { Point pp1 = new Point(p1.x, p1.y); Point pp2 = new Point(p1.x, p2.y); g2d.drawLine(p1.x, p1.y, p1.x, p2.y); switch (lineArrow) { case LINE_ARROW_DEST: paintArrow(g2d, pp1, pp2); break; case LINE_ARROW_SOURCE: paintArrow(g2d, pp2, pp1); break; case LINE_ARROW_BOTH: paintArrow(g2d, pp1, pp2); paintArrow(g2d, pp2, pp1); break; } } protected void paintHorizontal(Graphics2D g2d) { Point pp1 = new Point(p1.x, p1.y); Point pp2 = new Point(p2.x, p1.y); g2d.drawLine(p1.x, p1.y, p2.x, p1.y); switch (lineArrow) { case LINE_ARROW_DEST: paintArrow(g2d, pp1, pp2); break; case LINE_ARROW_SOURCE: paintArrow(g2d, pp2, pp1); break; case LINE_ARROW_BOTH: paintArrow(g2d, pp1, pp2); paintArrow(g2d, pp2, pp1); break; } }

protected void paintSimple(Graphics2D g2d) { g2d.drawLine(p1.x, p1.y, p2.x, p2.y); switch (lineArrow) { case LINE_ARROW_DEST: paintArrow(g2d, p1, p2); break; case LINE_ARROW_SOURCE: paintArrow(g2d, p2, p1); break; case LINE_ARROW_BOTH: paintArrow(g2d, p1, p2); paintArrow(g2d, p2, p1); break; } }

protected void paintArrow(Graphics2D g2d, Point p1, Point p2) { paintArrow(g2d, p1, p2, getRestrictedArrowWidth(p1, p2)); }

protected void paintArrow(Graphics2D g2d, Point p1, Point p2, int width) { Point2D.Float pp1 = new Point2D.Float(p1.x, p1.y); Point2D.Float pp2 = new Point2D.Float(p2.x, p2.y); Point2D.Float left = getLeftArrowPoint(pp1, pp2, width); Point2D.Float right = getRightArrowPoint(pp1, pp2, width);

Polygon arrowHead = new Polygon(); arrowHead.addPoint( p2.x, p2.y); arrowHead.addPoint( Math.round(left.x), Math.round(left.y)); arrowHead.addPoint( Math.round(right.x), Math.round(right.y)); Graphics2D g = (Graphics2D) g2d.create(); g.fill(arrowHead); g.dispose(); /* g2d.drawLine(p2.x, p2.y, Math.round(left.x), Math.round(left.y)); g2d.drawLine(p2.x, p2.y, Math.round(right.x), Math.round(right.y)); */ }

121

Page 133: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

protected void paint1Break(Graphics2D g2d) { if (lineStart == LINE_START_HORIZONTAL) { g2d.drawLine(p1.x, p1.y, p2.x, p1.y); g2d.drawLine(p2.x, p1.y, p2.x, p2.y); switch (lineArrow) { case LINE_ARROW_DEST: paintArrow(g2d, new Point(p2.x, p1.y), p2); break; case LINE_ARROW_SOURCE: paintArrow(g2d, new Point(p2.x, p1.y), p1); break; case LINE_ARROW_BOTH: paintArrow(g2d, new Point(p2.x, p1.y), p2); paintArrow(g2d, new Point(p2.x, p1.y), p1); break; } } else if (lineStart == LINE_START_VERTICAL) { g2d.drawLine(p1.x, p1.y, p1.x, p2.y); g2d.drawLine(p1.x, p2.y, p2.x, p2.y); switch (lineArrow) { case LINE_ARROW_DEST: paintArrow(g2d, new Point(p1.x, p2.y), p2); break; case LINE_ARROW_SOURCE: paintArrow(g2d, new Point(p1.x, p2.y), p1); break; case LINE_ARROW_BOTH: paintArrow(g2d, new Point(p1.x, p2.y), p2); paintArrow(g2d, new Point(p1.x, p2.y), p1); break; } } }

protected void paint2Breaks(Graphics2D g2d) { if (lineStart == LINE_START_HORIZONTAL) { g2d.drawLine(p1.x, p1.y, p1.x + (p2.x - p1.x) / 2, p1.y); g2d.drawLine(p1.x + (p2.x - p1.x) / 2, p1.y, p1.x + (p2.x - p1.x) / 2, p2.y); g2d.drawLine(p1.x + (p2.x - p1.x) / 2, p2.y, p2.x, p2.y); switch (lineArrow) { case LINE_ARROW_DEST: paintArrow(g2d, new Point(p1.x + (p2.x - p1.x) / 2, p2.y), p2); break; case LINE_ARROW_SOURCE: paintArrow(g2d, new Point(p1.x + (p2.x - p1.x) / 2, p1.y), p1); break; case LINE_ARROW_BOTH: paintArrow(g2d, new Point(p1.x + (p2.x - p1.x) / 2, p2.y), p2); paintArrow(g2d, new Point(p1.x + (p2.x - p1.x) / 2, p1.y), p1); break; } } else if (lineStart == LINE_START_VERTICAL) { g2d.drawLine(p1.x, p1.y, p1.x, p1.y + (p2.y - p1.y) / 2); g2d.drawLine(p1.x, p1.y + (p2.y - p1.y) / 2, p2.x, p1.y + (p2.y - p1.y) / 2); g2d.drawLine(p2.x, p1.y + (p2.y - p1.y) / 2, p2.x, p2.y);

switch (lineArrow) { case LINE_ARROW_DEST: paintArrow(g2d, new Point(p2.x, p1.y + (p2.y - p1.y) / 2), p2); break; case LINE_ARROW_SOURCE: paintArrow(g2d, new Point(p1.x, p1.y + (p2.y - p1.y) / 2), p1); break; case LINE_ARROW_BOTH: paintArrow(g2d, new Point(p2.x, p1.y + (p2.y - p1.y) / 2), p2); paintArrow(g2d, new Point(p1.x, p1.y + (p2.y - p1.y) / 2), p1); break; } } }

public int getLineType() { return lineType; }

public void setLineType(int type) { lineType = type; }

public int getLineStart() { return lineStart; }

public void setLineStart(int start) { lineStart = start; }

public int getLineArrow() { return lineArrow;

122

Page 134: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

}

public void setLineArrow(int arrow) { lineType = lineArrow; }

public Point getP1() { return p1; }

public void setP1(Point p) { p1 = p; }

public Point getP2() { return p2; }

public void setP2(Point p) { p2 = p; }

protected static Point2D.Float getMidArrowPoint(Point2D.Float p1, Point2D.Float p2, float w) { Point2D.Float res = new Point2D.Float(); float d = Math.round(Math.sqrt( (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)));

if (p1.x < p2.x) { res.x = p2.x - w * Math.abs(p1.x - p2.x) / d; } else { res.x = p2.x + w * Math.abs(p1.x - p2.x) / d; }

if (p1.y < p2.y) { res.y = p2.y - w * Math.abs(p1.y - p2.y) / d; } else { res.y = p2.y + w * Math.abs(p1.y - p2.y) / d; }

return res; }

protected static Point2D.Float getLeftArrowPoint(Point2D.Float p1, Point2D.Float p2) { return getLeftArrowPoint(p1, p2, LINE_ARROW_WIDTH); }

protected static Point2D.Float getLeftArrowPoint(Point2D.Float p1, Point2D.Float p2, float w) { Point2D.Float res = new Point2D.Float(); double alpha = Math.PI / 2; if (p2.x != p1.x) { alpha = Math.atan( (p2.y - p1.y) / (p2.x - p1.x)); } alpha += Math.PI / 5; float xShift = Math.abs(Math.round(Math.cos(alpha) * w)); float yShift = Math.abs(Math.round(Math.sin(alpha) * w)); if (p1.x <= p2.x) { res.x = p2.x - xShift; } else { res.x = p2.x + xShift; } if (p1.y < p2.y) { res.y = p2.y - yShift; } else { res.y = p2.y + yShift; } return res; }

protected static Point2D.Float getRightArrowPoint(Point2D.Float p1, Point2D.Float p2) { return getRightArrowPoint(p1, p2, LINE_ARROW_WIDTH); }

protected static Point2D.Float getRightArrowPoint(Point2D.Float p1, Point2D.Float p2, float w) { Point2D.Float res = new Point2D.Float(); double alpha = Math.PI / 2; if (p2.x != p1.x) { alpha = Math.atan( (p2.y - p1.y) / (p2.x - p1.x)); } alpha -= Math.PI / 5; float xShift = Math.abs(Math.round(Math.cos(alpha) * w)); float yShift = Math.abs(Math.round(Math.sin(alpha) * w)); if (p1.x < p2.x) { res.x = p2.x - xShift; } else { res.x = p2.x + xShift; } if (p1.y <= p2.y) { res.y = p2.y - yShift;

123

Page 135: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

} else { res.y = p2.y + yShift; } return res; }

protected int getRestrictedArrowWidth(Point p1, Point p2) { return Math.min(LINE_ARROW_WIDTH, (int) Math.sqrt( (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y))); }}

124

Page 136: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.5 LineCode.java package xenon;

import xenon.XenonHelper.PseudoInstruction;

/*** @brief Contiene la información de una línea de texto del código ensamblador. * Es una clase intermediaria usada en la compilación del código ensamblador.*/

public class LineCode{public Instruction instruction;public String label;public int address; //Posición de memoria donde se encuentra esta instrucción, no confundir con

LineCode.instruction.getMemoryAddress.public String addressLabel; // Necesario en un paso intermedio. Hay que traducirlo y meterlo en

LineCode.instruction.setMemoryAddress.public int lineNumber;public PseudoInstruction pseudoInstruction;

LineCode(){

instruction = new Instruction();label = null;address = -1;addressLabel = null;pseudoInstruction = null;lineNumber = -1;

}public String toString(){

String s = new String();return s;

}public int check(){

int r = 0;if(lineNumber < 0){

r = -1;}else if(address < 0 || address > Instruction.Memory_Address_Limit){

System.out.println("Error: address " + address + " out of bounds");r = -2;

}else if(pseudoInstruction == null){

if(instruction == null){

r = -3;}else if( instruction.isInstruction() ){

//Es una instrucción}else if( !instruction.isInstruction() ){

//Es simplemente datos}

}else if(pseudoInstruction != null){

switch(pseudoInstruction){

case ORG:

//Todo OKbreak;

case FIN://No deberíamos haber guardado esta pseudo instrucción!!r = -4;break;

case ESP:int d = 0;try {

instruction.setInstructionSigned(d);}catch(Exception e){

}break;

case CTE:break;

}

}return r; } };

125

Page 137: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.6 Sobre.java package xenon;

import java.awt.event.ActionEvent;import java.awt.event.ActionListener;

import javax.swing.JButton;import javax.swing.JDialog;import javax.swing.JLabel;import javax.swing.UIManager;import javax.swing.GroupLayout;

/** * @brief Esta clase implementa una ventana popup que muestra información sobre el autor * del proyecto, así como del profesor tutor del mismo. * */

public class Sobre extends JDialog implements ActionListener{

/** * */private static final long serialVersionUID = 1L;

/** * Lanzar ventana/aplicación */public static void main(String[] args) {

try {Sobre dialog = new Sobre(0,0);

dialog.setVisible(true);} catch (Exception e) {

e.printStackTrace();}

}

public void actionPerformed(ActionEvent e) {//No cierra toda la aplicación, solo esta ventana.

dispose(); }

/** * Crear diálogo. */public Sobre(int xoffset, int yoffset) {

setBounds(285+xoffset, 220+yoffset, 360, 245);setTitle("Sobre este programa");setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

JLabel infoIcon = new JLabel( UIManager.getIcon("OptionPane.informationIcon"));JLabel info1 = new JLabel(" CESIUS IDE v0.3");JLabel info2 = new JLabel("© Copyright 2013");JLabel info3 = new JLabel("Proyecto Fin de Carrera");JLabel info4 = new JLabel("E.T.S.I. Universidad de Sevilla");JLabel info5 = new JLabel("Autor: Félix Robles Elvira,");JLabel info6 = new JLabel("e-mail: [email protected]");JLabel info7 = new JLabel("Tutor: José Ángel Acosta Rodríguez,");JLabel info8 = new JLabel("e-mail: [email protected]");JLabel info9 = new JLabel("Licencia GPLv3.0");JButton okButton = new JButton("OK");okButton.addActionListener(this);

GroupLayout groupLayout = new GroupLayout(getContentPane());groupLayout.setHorizontalGroup(

groupLayout.createSequentialGroup().addGap(30).addComponent(infoIcon).addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.CENTER)

.addComponent(info1)

.addComponent(info2)

.addComponent(info3)

.addComponent(info4)

.addComponent(info5)

.addComponent(info6)

.addComponent(info7)

.addComponent(info8)

.addComponent(info9)

.addComponent(okButton))

);groupLayout.setVerticalGroup(groupLayout.createSequentialGroup()

.addGap(10)

.addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(infoIcon).addComponent(info1))

.addComponent(info2).addComponent(info3)

126

Page 138: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

.addComponent(info4)

.addComponent(info5)

.addComponent(info6)

.addComponent(info7)

.addComponent(info8)

.addComponent(info9)

.addGap(20)

.addComponent(okButton));getContentPane().setLayout(groupLayout);

}

}

127

Page 139: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.7 ConnectorContainer.java

package xenon;import javax.swing.*;import java.awt.*;import java.util.ArrayList;

/** * The collateral class contains array of connectors and renders them. * The rendering can be called in a different way. E.g. JConnectors can be just * added as usual component. In this case programmer must care about their size, * and layout. * * <p>Copyright: Copyright (c) 2007</p> * * @author Stanislav Lapitsky * @version 1.0 */

/** * @brief Una de las clases usada para pintar flechitas de un lado a otro * @detail Librería modificada por Félix Robles, código original de Stanislav Lapitsky. */ public class ConnectorContainer extends JPanel { /**

* */private static final long serialVersionUID = 1L;ArrayList<JConnector> connectors;/** * @brief Constructor de la clase, inicializa el atributo connectors. */

public ConnectorContainer() { connectors = new ArrayList<JConnector> (); }

/** * @brief Añade un conector al panel. */

public void addConnector(JConnector c) { connectors.add(c); }

/** * @brief Añade una lista de conectores al panel. */

public void addConnectors(ArrayList<JConnector> c) { for(JConnector i: c) { connectors.add(i); } }

/** * @brief Devuelve los conectores del panel. */

public ArrayList<JConnector> getConnectors() { return connectors; }

/** * @brief Pinta los conectores del panel. */

public void paint(Graphics g) { super.paint(g); for(JConnector c: connectors) { c.paint(g); } }}

128

Page 140: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.8 PopupListener.java package xenon;

import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;

import javax.swing.JPopupMenu;

/** * * @brief Esta clase hace de listener de forma que muestra un popup cuando lo activa el ratón. * */class PopupListener extends MouseAdapter {

private JPopupMenu popup;PopupListener(JPopupMenu p){

popup = p;}

public void mousePressed(MouseEvent e) { showPopup(e); }

public void mouseReleased(MouseEvent e) { showPopup(e); }

private void showPopup(MouseEvent e) { if (e.isPopupTrigger()) { popup.show(e.getComponent(), e.getX(), e.getY()); } }}

129

Page 141: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.9 Tab.java package xenon;

import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.io.BufferedReader;import java.io.FileReader;

import javax.swing.JLabel;import javax.swing.JScrollPane;import javax.swing.JTextArea;

import xenon.ProjectFile.FileType;

/** * * @brief Esta clase define una pestaña. * */public class Tab extends JScrollPane implements KeyListener{

/** * */public static final long serialVersionUID = -8100218024452896927L;public ProjectFile pFile; //Fichero que contiene la pestañapublic JTextArea textArea; //Área de texto de la pestañaprivate JLabel label; //Etiqueta de la pestañaprivate boolean isModified; //Indica si el texto ha sido modificado y todavía no se ha guardado

/** * @brief Modifica la etiqueta de la pestaña. * @param l */public void setLabel(JLabel l){

label = l;}/** * @brief Indica si hay cambios no guardados del fichero. * @return */public boolean isModified(){

return isModified;}/** * @brief Marca el fichero como modificado/no modificado. * @param b */public void setModified(boolean b){

if(isModified == false && b == true){

label.setText("*" + label.getText());}else if (isModified == true && b == false){

label.setText(label.getText().substring(1));}isModified = b;

}

/** * Constructor * @param ta JTextArea de la pestaña * @param pf Fichero que contiene la pestaña */Tab(JTextArea ta, ProjectFile pf){

super(ta);textArea = ta;pFile = pf;isModified = false;label = null;

if(pFile.type == ProjectFile.FileType.TEXT || pFile.type == ProjectFile.FileType.CODE){

try {String strLine;

BufferedReader br = new BufferedReader(new FileReader(pFile.file));

while((strLine = br.readLine()) != null) { textArea.append(strLine + "\n"); }}catch(Exception e)

{

130

Page 142: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

System.err.println("Error: " + e.getMessage()); }

}else if(pFile.type == ProjectFile.FileType.BINARY){

textArea.setEditable(false);}textArea.addKeyListener(this);

}

/** * Al escribir en una pestaña, indicamos que el archivo de texto está siendo modificado. */@Overridepublic void keyPressed(KeyEvent arg0) {

if(pFile.type != FileType.BINARY){

setModified(true);}

}

@Overridepublic void keyReleased(KeyEvent arg0) {

}

@Overridepublic void keyTyped(KeyEvent arg0) {

}}

131

Page 143: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.10 DebugViewManager.java package xenon;

import java.awt.Color;import java.awt.Component;import java.awt.Dimension;import java.awt.event.ActionEvent;import java.awt.event.ItemEvent;import java.awt.event.ItemListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.event.MouseListener;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.util.ArrayList;import java.util.Timer;import java.util.TimerTask;import java.util.Vector;

import javax.swing.AbstractAction;import javax.swing.Action;import javax.swing.BorderFactory;import javax.swing.GroupLayout;import javax.swing.GroupLayout.Alignment;import javax.swing.ImageIcon;import javax.swing.JLabel;import javax.swing.JPopupMenu;import javax.swing.JScrollPane;import javax.swing.JSplitPane;import javax.swing.JTabbedPane;import javax.swing.JTable;import javax.swing.JTextField;import javax.swing.JTextPane;import javax.swing.ListSelectionModel;import javax.swing.event.ListSelectionEvent;import javax.swing.event.ListSelectionListener;import javax.swing.table.DefaultTableCellRenderer;import javax.swing.table.DefaultTableModel;

import xenon.VirtualComputer.ComputerRegister;import xenon.VirtualComputer.ComputerSignal;import xenon.VirtualComputer.ComputerState;

/** * @brief Clase gestora de la vista de depuración. * @detail Esta clase realiza todas las tareas de la interfaz gráfica de la vista de depuración, * además de lidiar con la clase VirtualComputer. */ public class DebugViewManager extends JSplitPane implements VirtualComputer.VirtualComputerListener, ItemListener{

/** * * @brief Base usada para representar los registros y el contenido de la memoria. * */public enum Base { BINARY, DECIMAL, HEXADECIMAL };

/** * * @brief FALSE: Actualmente no se está pidiendo ningún dato de entrada. * CARACTER: El computador necesita un carácter como dato de entrada. * NUMBER: El computador necesita un número como dato de entrada. * */public enum InputType {

FALSE,CARACTER, NUMBER };

private boolean isCheckBoxSelected, executeSemisteps;private JTextPane consolaPane; //Consola de entrada y salida de datosprivate ConsoleKeyListener consolaListener; //Listener que recoge y trata la entrada proveniente del teclado//Buffer de entrada. Se van añadiendo datos hasta recibir un enter (en el caso de que el computador esté pidiendo datos)private String inputBuffer;private long period; //Período de reloj de una instrucción

del computador en milisegundos = 1000/fprivate int runTo; //En el caso de "Ejecutar Hasta",

dirección de memoria en la que parar la ejecuciónprivate ColorCellRenderer pTableRenderer; //Renderer de la tabla pTableprivate ColorCellRenderer memoriaTableRenderer;//Renderer de la tabla memoriaTableprivate File debugFile;private Trace execTrace;

//Variables que sirven para mantener la cuenta del reloj del computadorpublic long startTime;

132

Page 144: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

public long nextTime, nextTime2;//Timer usado para organizar la ejecución de instrucciones en modo runModeTimer instructionTimer;//Timer usado para los cambios de registroTimer changesTimer;//Tarea de ejecución de una instrucciónExecuteInstructionTask instructionTask;//Etiqueta del reloj del computadorJLabel timeLabel;//Tablas de memoria. pTable muestra la memoria entorno a P.private JTable pTable, memoriaTable;//Etiquetas que muestran el contenido de los registros del computadorprivate FlashyTextField textFieldA, textFieldP, textFieldS, textFieldI, textFieldT, textFieldE, textFieldCO, textFieldMD;//Etiquetas que muestran las señales del computadorprivate FlashySignal etLabel, stLabel, eeLabel, seLabel, escpLabel, leetLabel, eaLabel, saLabel, eoLabel, sumaLabel, resaLabel, multaLabel, incpLabel, epLabel, spLabel, esLabel, sdLabel, eiLabel, lecmLabel, escmLabel, divaLabel,

modaLabel;//Etiquetas CO/MD/D que han de ser no visibles cuando no estamos en modo binarioJLabel coLabel, mdLabel, dLabel;//Variable que contiene la base que actualmente se usa para representar datosprivate Base base;//Instancia del computador que se está emulandoprivate VirtualComputer computer;

/** * */private static final long serialVersionUID = 1L;

/** * @brief Esta clase sirve para crear una traza de la ejecución del programa. */class Trace{

File f;Trace(File file){

String dir = file.getParent();f = new File(dir + "/traza.txt");System.out.println(f.getAbsolutePath());restart();

}public void restart(){

try {BufferedWriter outFile = new BufferedWriter(new FileWriter(f, false));outFile.write("Address\t\tP\t\tI\t\tA\t\tT\t\tS\t\tS");outFile.newLine();outFile.close();

}catch (IOException ex) {

}}public void registerStep(Instruction i, VirtualComputer.ComputerState s){

try {BufferedWriter outFile = new BufferedWriter(new FileWriter(f, true));

outFile.write(i.getAddressLocation() + "\t\t" + s.getP() + "\t\t" + i.getOperationCode().name() + " " + i.getInstructionOperator()

+ "\t\t" + s.getA() + "\t\t" + s.getT() + "\t\t" + s.getS() + "\t\t" + s.getE()); //put in textfileoutFile.newLine();outFile.close();

}catch (IOException ex) {

}}

}/** * @brief Tarea que ejecuta una instrucción. * @detail El timer instructionTimer llamará a la función run() una vez por el período de tiempo fijado. * Esa función se encarga de ejecutar la siguiente instrucción. */

class ExecuteInstructionTask extends TimerTask{

@Overridepublic void run() {

//Hemos llegado a la instrucción en la que queríamos pararif(runTo != -1 && computer.getState().getP() == runTo){

actionPause();}//Si el computador no está pidiendo datos de entrada, ejecutamos la siguiente instrucciónelse if(consolaListener.getPidiendoDatos() == InputType.FALSE){

executeNextInstruction();

if(startTime > 0){

//Actualizamos el tiempo de ejecución después de ejecutar cada instruccióntimeLabel.setText(addZeros((System.currentTimeMillis()-startTime)+"", 6) + " ms");

133

Page 145: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

}}

}public void stop(){

this.cancel();}

}

/** * @brief Clase que escucha cuándo se selecciona una nueva posición de memoria. * @detail Cuando el usuario seleccione una posición de memoria en la tabla, el registro P cambiará su valor. */

class TableListener implements ListSelectionListener{

@Overridepublic void valueChanged(ListSelectionEvent arg0) {

try{

if(computer.getState().getP() != pTable.getSelectedRow()){

consolaListener.setPidiendoDatos(InputType.FALSE);computer.getState().setP(pTable.getSelectedRow());computer.getState().setRegisterChanged(ComputerRegister.P, true);computer.getState().sendSignals();

}

}catch(Exception e){

}}

}

/** * @brief Clase que escucha la entrada del teclado y la representa en la consola. * @detail Cuando el usuario presione ENTER, los datos se mandarán al computador. */

class ConsoleKeyListener implements KeyListener{

private InputType inputAsked;

/** * Informa al listener de si el computador está pidiendo datos. * @param b Define si el computador está pidiendo datos, y de qué tipo */public void setPidiendoDatos(InputType b){

inputAsked = b;if(inputAsked != InputType.FALSE){

consolaPane.requestFocus();if(inputAsked == InputType.CARACTER){

consolaPane.setText(consolaPane.getText() + "\nIntroduzca un carácter: ");

}else if(inputAsked == InputType.NUMBER){

consolaPane.setText(consolaPane.getText() + "\nIntroduzca un número: ");

}}

}/** * @brief Informa de si actualmente el computador está a la espera de datos de entrada. */public InputType getPidiendoDatos(){

return inputAsked;}

void displayInfo(KeyEvent e){

if(e.getModifiers() == 0 &&inputAsked != InputType.FALSE){

String s = consolaPane.getText();int id = e.getID();if (id == KeyEvent.KEY_TYPED) {

s += e.getKeyChar(); }

consolaPane.setText(s);if(inputBuffer == null)

134

Page 146: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

{inputBuffer = new String("");

}//Cuando se pulsa Enter, se envían los datos al computadorif(KeyEvent.VK_ENTER == e.getKeyChar()){

String in = getConsoleInput();Instruction.OperationCode op = computer.getNextInstruction().getOperationCode();Instruction nextIns = new Instruction();try{

nextIns.setInstructionSigned(computer.getNextInstruction().getDataSigned());nextIns.setAddressLocation(computer.getNextInstruction().getAddressLocation());

} catch (Exception ee){

}if(in == null){

//Se ha pulsado enter pero no se han introducido datostry{

computer.getState().setE(0);computer.getState().setRegisterChanged(ComputerRegister.E, true);computer.getState().sendSignals();}

catch (Exception x){

}}else{

if(inputAsked == InputType.NUMBER){

//El dato pedido es un númerotry{

int inn = Integer.parseInt(in);try{

computer.getState().setE(inn);

computer.getState().setRegisterChanged(ComputerRegister.E, true);computer.getState().sendSignals();

}catch (Exception xx){

//TODO:}

}catch (NumberFormatException nfe) {

//TODO:}

}else if(inputAsked == InputType.CARACTER){

//El dato pedido es un carácterif(in.length() == 1){

try{int inn =

(char)in.charAt(0);//Character.getNumericValue(in.charAt(0));try{

computer.getState().setE(inn);

computer.getState().setRegisterChanged(ComputerRegister.E, true);computer.getState().sendSignals();

}catch (Exception xx){

//TODO:}

}catch (NumberFormatException nfe) {

//TODO:}}else{

//TODO: Error la cadena introducida es demasiado larga (debería ser 1 solo carácter).

}}

}try{

if(executeSemisteps == false){

computer.executeNextInstruction();}else if(executeSemisteps == true){

if(computer.getSemistepInfo() == VirtualComputer.Last_Semistep){

computer.executeSemistep();

135

Page 147: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

}}

if(execTrace != null){

execTrace.registerStep(nextIns, computer.getState());}if(nextTime > 0){

nextTime = System.currentTimeMillis()-nextTime2+nextTime;timeLabel.setText(addZeros(nextTime+"", 6) + " ms");

}else if( startTime > 0){

timeLabel.setText(addZeros((System.currentTimeMillis()-startTime)+"", 6) + " ms");

}}catch(Exception excep){

}

setPidiendoDatos(InputType.FALSE);}else // Si no se ha pulsado ENTER, añadimos la entrada del teclado al buffer de entrada{

inputBuffer += e.getKeyChar();}

}}

@Overridepublic void keyPressed(KeyEvent e) {}

@Overridepublic void keyReleased(KeyEvent e) {}

//Esta función es llamada cada vez que se pulsa una tecla mientras la consola esté enfocada.@Overridepublic void keyTyped(KeyEvent e) {

displayInfo(e);}

}

/** * * @brief Esta clase sirve para resaltar las posiciones de memoria que cambian en la JTable correspondiente * */class ColorCellRenderer extends DefaultTableCellRenderer{

JTable table; //Tabla a la que pertenecen las celdasprivate int dir;/** * */

ColorCellRenderer(JTable t){

table = t;dir = -1;

this.setHorizontalAlignment(RIGHT);}private static final long serialVersionUID = 1L;

@Overridepublic Component getTableCellRendererComponent(JTable table, Object value,

boolean isSelected, boolean hasFocus, int row, int column) {Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row,

column);//cellComponent.setBackground(Color.WHITE);if(row != dir && !isSelected){

cellComponent.setBackground(Color.WHITE);}else if(row == dir && !isSelected){

cellComponent.setBackground(new Color(0, 184, 245));}return cellComponent;

}void restart(){

dir = -1;table.repaint();

}

136

Page 148: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

void flash(int row){

if (row >= 0 && row < table.getRowCount()){

if(dir != row){

dir = row;table.repaint();

}}

}

}/** * * @brief Versión de JLabel que sirve para marcar cuándo se usan las señales del computador * */class FlashySignal extends JLabel{

/** * */private static final long serialVersionUID = 1L;FlashySignal(String s, Timer t){

super(s);setForeground(Color.LIGHT_GRAY);

}/** * @brief Desmarca la señal */public void restart(){

setForeground(Color.LIGHT_GRAY);}/** * Marca la señal */public void flash(Color c){

//setForeground(new Color(0, 184, 245));setForeground(c);

}}/** * @brief Versión de JTextField que marca en azul cuando un registro es actualizado. */class FlashyTextField extends JTextField{

/** * */private static final long serialVersionUID = 1L;private Color baseBackground;

FlashyTextField(String text, Timer t){

super(text);baseBackground = new Color(238,238, 238); //fondo gris

}

/** * @brief Desmarca la señal */public void restart(){

setBackground(baseBackground);}/** * Marca la señal */public void flash(Color c){

if(getBackground() != c){

setBackground(c);}

}

}

/** * @detail Método que sirve para dar a conocer a la vista de depuración si * el computador está a la espera de datos. * @param b */public void setPidiendoDatos(InputType b){

consolaListener.setPidiendoDatos(b);}

137

Page 149: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

/** * @brief Método que cambia la base en que se muestran los datos */public void setRegistersBase(Base b){

base = b;if(base == Base.BINARY){

//En este caso mostramos CO y MDtextFieldCO.setBorder(textFieldA.getBorder());textFieldMD.setBorder(textFieldA.getBorder());coLabel.setForeground(Color.BLACK);mdLabel.setForeground(Color.BLACK);dLabel.setForeground(Color.BLACK);

}else{

//En este caso ocultamos CO y MDtextFieldCO.setBorder(BorderFactory.createLineBorder(new Color(238, 238, 238)));textFieldMD.setBorder(BorderFactory.createLineBorder(new Color(238, 238, 238)));coLabel.setForeground(new Color(238, 238, 238));mdLabel.setForeground(new Color(238, 238, 238));dLabel.setForeground(new Color(238, 238, 238));

}updateJTableModel();stateChanged();

}

/** * Método que cambia el período de ejecución. Este cambio de período se notará la siguiente vez * que se ejecute el código en modo "Ejecutar todo" o "Ejecutar hasta" * @param millisecs */public void setExecutionPeriod(long millisecs){

period = millisecs;}

/** * @detail Devuelve los datos del buffer de entrada del teclado * @return */public String getConsoleInput(){

String r = null;if(inputBuffer != null){

r = new String(inputBuffer);}inputBuffer = null;return r;

}

/** * @detail Añade el texto del parámetro text a la consola * @param text */public void addConsoleOutput(String text){

String s = consolaPane.getText();s += text;consolaPane.setText(s);

}/** * @brief Centra la tabla pTable en la posición indicada por el parámetro de entrada p * @param p */public void selectNextInstructionInMemoryNearP(int p){

int count = (int)pTable.getRowCount();if(p >= 0 && p < count && count > 0){

pTable.setRowSelectionInterval(p, p);int scrollTo = Math.min(p+7, count-1);if(scrollTo >= 0 && scrollTo < count){

pTable.scrollRectToVisible(pTable.getCellRect(scrollTo, 0, true));}

}}/** * @detail Acción "Ejecutar Todo". Ejecuta las instrucciones del ordenador hasta llegar a un ALT, * con la frecuencia del computador seleccionada. */public void actionRun(){

if(instructionTask == null){

//runMode = true;if(isCheckBoxSelected == false)

138

Page 150: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

{executeSemisteps = false;consolaListener.setPidiendoDatos(InputType.FALSE);instructionTask = new ExecuteInstructionTask();instructionTimer.scheduleAtFixedRate(instructionTask, 0, period);startTime = System.currentTimeMillis();nextTime = -1;

}else if (isCheckBoxSelected == true){

executeSemisteps = true;consolaListener.setPidiendoDatos(InputType.FALSE);instructionTask = new ExecuteInstructionTask();instructionTimer.scheduleAtFixedRate(instructionTask, 0, period/2);startTime = System.currentTimeMillis();nextTime = -1;

}}

}

/** * @detail Acción "Ejecutar Todo". Ejecuta las instrucciones del ordenador hasta llegar a cierta instrucción, * o a un ALT, con la frecuencia del computador seleccionada. */public void actionRunTo(int num){

actionPause();if(instructionTask == null && num >= 0 && num <= Instruction.Memory_Address_Limit){

//runMode = true;if(isCheckBoxSelected == false){

executeSemisteps = false;runTo = num;consolaListener.setPidiendoDatos(InputType.FALSE);instructionTask = new ExecuteInstructionTask();instructionTimer.scheduleAtFixedRate(instructionTask, 0, period);startTime = System.currentTimeMillis();nextTime = -1;

}else if (isCheckBoxSelected == true){

executeSemisteps = true;runTo = num;consolaListener.setPidiendoDatos(InputType.FALSE);instructionTask = new ExecuteInstructionTask();instructionTimer.scheduleAtFixedRate(instructionTask, 0, period/2);startTime = System.currentTimeMillis();nextTime = -1;

}}

}

/** * @detail Acción Pausar. Detiene la ejecución de instrucciones. */public void actionPause(){

//runMode = false;runTo = -1;if(instructionTask != null){

instructionTask.cancel();instructionTask = null;

}}

/** * @detail Acción Reiniciar. Reinicia el estado del computador. */public void actionRestart(){

if(execTrace != null){

execTrace.restart();}pTableRenderer.restart();memoriaTableRenderer.restart();runTo = -1;if(instructionTask != null){

instructionTask.cancel();instructionTask = null;

}consolaPane.setText("");startTime = -1;nextTime = -1;timeLabel.setText(addZeros("0", 6) + " ms");try{

computer.restart();

139

Page 151: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

consolaListener.setPidiendoDatos(InputType.FALSE);}catch(Exception e){

}}

/** * @detail Acción Ejecutar siguiente instrucción. Solo ejecuta una instrucción. */public void actionExecuteNextInstruction(){

if(isCheckBoxSelected == false){

executeSemisteps = false;}else if (isCheckBoxSelected == true){

executeSemisteps = true;}executeNextInstruction();

}

public void executeNextInstruction(){

pTableRenderer.restart();memoriaTableRenderer.restart();if(nextTime < 0){

nextTime = 0;}nextTime2 = System.currentTimeMillis();if(executeSemisteps == false){

//Check if next instruction needs some kind of input.Instruction.OperationCode op = computer.getNextInstruction().getOperationCode();Instruction nextIns = new Instruction();try{

nextIns.setInstructionSigned(computer.getNextInstruction().getDataSigned());nextIns.setAddressLocation(computer.getNextInstruction().getAddressLocation());

} catch (Exception e){

}if(op == Instruction.OperationCode.LCA || op == Instruction.OperationCode.LCAI ){

/* * In that case the instruction will be executed when when we get the input. */setPidiendoDatos(InputType.CARACTER);

}else if(op == Instruction.OperationCode.LEE || op == Instruction.OperationCode.LEEI){

/* * In that case the instruction will be executed when when we get the input. */setPidiendoDatos(InputType.NUMBER);

}else{

//If it's not needed, execute instruction.if(op == Instruction.OperationCode.ALT){

actionPause();nextTime = System.currentTimeMillis()-nextTime2+nextTime;timeLabel.setText(addZeros(nextTime+"", 6) + " ms");

}else{

try{computer.executeNextInstruction();if(execTrace != null){

execTrace.registerStep(nextIns, computer.getState());}nextTime = System.currentTimeMillis()-nextTime2+nextTime;timeLabel.setText(addZeros(nextTime+"", 6) + " ms");

}catch(Exception e){

//TODO: Catch exception}

}}

}else if (executeSemisteps == true){

if(computer.getSemistepInfo() == VirtualComputer.First_Semistep){

try{computer.executeSemistep();

140

Page 152: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

}catch (Exception e){

}}else if(computer.getSemistepInfo() == VirtualComputer.Last_Semistep){

//Check if next instruction needs some kind of input.Instruction.OperationCode op = computer.getNextInstruction().getOperationCode();Instruction nextIns = new Instruction();try{

nextIns.setInstructionSigned(computer.getNextInstruction().getDataSigned());nextIns.setAddressLocation(computer.getNextInstruction().getAddressLocation());

} catch (Exception e){

}if(op == Instruction.OperationCode.LCA || op == Instruction.OperationCode.LCAI ){

/* * In that case the instruction will be executed when when we get the input. */setPidiendoDatos(InputType.CARACTER);

}else if(op == Instruction.OperationCode.LEE || op == Instruction.OperationCode.LEEI){

/* * In that case the instruction will be executed when when we get the input. */setPidiendoDatos(InputType.NUMBER);

}else{

//If it's not needed, execute instruction.if(op == Instruction.OperationCode.ALT){

actionPause();nextTime = System.currentTimeMillis()-nextTime2+nextTime;timeLabel.setText(addZeros(nextTime+"", 6) + " ms");

}else{

try{computer.executeSemistep();if(execTrace != null){

execTrace.registerStep(nextIns, computer.getState());}nextTime = System.currentTimeMillis()-nextTime2+nextTime;timeLabel.setText(addZeros(nextTime+"", 6) + " ms");

}catch(Exception e){

//TODO: Catch exception}

}}

}}

}

/** * @detail Cuando cierta posición de memoria cambia, este método es llamado para actualizar * la fila adecuada de tabla de memoria de la interfaz gráfica. */public void changeMemoryAddress(Instruction i) throws IndexOutOfBoundsException{

int ma = i.getAddressLocation();DefaultTableModel tModel = (DefaultTableModel) pTable.getModel();DefaultTableModel mModel = (DefaultTableModel) memoriaTable.getModel();

if(ma >= 0 && ma < tModel.getRowCount()){

//colorRenderer.flash(memoriaTable, ma, changesTimer);if(i.isInstruction()){

tModel.setValueAt(Integer.toString(ma), ma, 0);tModel.setValueAt(i.getOperationCode().name(), ma, 1);tModel.setValueAt(Integer.toString(i.getInstructionOperator()), ma, 2);

if(base == Base.DECIMAL){

tModel.setValueAt(Integer.toString(i.getDataSigned()), ma, 3);mModel.setValueAt(Integer.toString(i.getDataSigned()), ma, 3);

}else if(base == Base.BINARY){

tModel.setValueAt(addZeros(Integer.toString(i.getDataUnsigned(), 2), 16), ma, 3);mModel.setValueAt(addZeros(Integer.toString(i.getDataUnsigned(), 2), 16), ma, 3);

}else if(base == Base.HEXADECIMAL)

141

Page 153: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

{tModel.setValueAt(addZeros(Integer.toString(i.getDataUnsigned(), 16), 4), ma, 3);mModel.setValueAt(addZeros(Integer.toString(i.getDataUnsigned(), 16), 4), ma, 3);

}

mModel.setValueAt(Integer.toString(ma), ma, 0);mModel.setValueAt(i.getOperationCode().name(), ma, 1);mModel.setValueAt(Integer.toString(i.getInstructionOperator()), ma, 2);

}else{

tModel.setValueAt(Integer.toString(ma), ma, 0);tModel.setValueAt("", ma, 1);tModel.setValueAt("", ma, 2);

if(base == Base.DECIMAL){

tModel.setValueAt(Integer.toString(i.getDataSigned()), ma, 3);mModel.setValueAt(Integer.toString(i.getDataSigned()), ma, 3);

}else if(base == Base.BINARY){

tModel.setValueAt(addZeros(Integer.toString(i.getDataUnsigned(), 2), 16), ma, 3);mModel.setValueAt(addZeros(Integer.toString(i.getDataUnsigned(), 2), 16), ma, 3);

}else if(base == Base.HEXADECIMAL){

tModel.setValueAt(addZeros(Integer.toString(i.getDataUnsigned(), 16), 4), ma, 3);mModel.setValueAt(addZeros(Integer.toString(i.getDataUnsigned(), 16), 4), ma, 3);

}

mModel.setValueAt(Integer.toString(ma), ma, 0);mModel.setValueAt("", ma, 1);mModel.setValueAt("", ma, 2);

}}else{

throw new IndexOutOfBoundsException(i.toString());}

}

/** * @detail Cuando muchas posiciones de memoria cambian, este método es llamado para actualizar * la tabla de memorian entera de la interfaz gráfica. */private void updateJTableModel(){

String[] columnas = {"Dirección","Instrucción", "Operador", "Dato" };DefaultTableModel tModel = (new DefaultTableModel(){

/** * */private static final long serialVersionUID = 1L;

public boolean isCellEditable(int rowIndex, int colIndex) { return false;}

});

DefaultTableModel mModel = (new DefaultTableModel(){

/** * */private static final long serialVersionUID = 1L;

public boolean isCellEditable(int rowIndex, int colIndex) { return false;}

});

pTable.setModel(tModel);memoriaTable.setModel(mModel);tModel.setColumnIdentifiers(columnas);mModel.setColumnIdentifiers(columnas);

DefaultTableCellRenderer rightRenderer = new DefaultTableCellRenderer();rightRenderer.setHorizontalAlignment( DefaultTableCellRenderer.RIGHT );pTable.getColumnModel().getColumn(3).setCellRenderer( rightRenderer );pTable.getColumnModel().getColumn(0).setMaxWidth(80);pTable.getColumnModel().getColumn(1).setMaxWidth(80);pTable.getColumnModel().getColumn(2).setMaxWidth(80);memoriaTable.getColumnModel().getColumn(3).setCellRenderer( rightRenderer );memoriaTable.getColumnModel().getColumn(0).setMaxWidth(80);memoriaTable.getColumnModel().getColumn(1).setMaxWidth(80);memoriaTable.getColumnModel().getColumn(2).setMaxWidth(80);

DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();centerRenderer.setHorizontalAlignment( DefaultTableCellRenderer.CENTER );

142

Page 154: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

pTable.getColumnModel().getColumn(2).setCellRenderer( centerRenderer );memoriaTable.getColumnModel().getColumn(2).setCellRenderer( centerRenderer );pTable.getColumnModel().getColumn(1).setCellRenderer( centerRenderer );memoriaTable.getColumnModel().getColumn(1).setCellRenderer( centerRenderer );pTable.getColumnModel().getColumn(0).setCellRenderer( centerRenderer );memoriaTable.getColumnModel().getColumn(0).setCellRenderer( centerRenderer );

Vector<String> line;for(Instruction i: computer.getMemoryMap()){

line = new Vector<String>();

if(i.isInstruction() == true){

line.add(Integer.toString(i.getAddressLocation()));line.add(i.getOperationCode().name());line.add(Integer.toString(i.getInstructionOperator()));

if(base == Base.DECIMAL){

line.add(Integer.toString(i.getDataSigned()));}else if(base == Base.BINARY){

line.add(addZeros(Integer.toString(i.getDataUnsigned(), 2), 16) );}else if(base == Base.HEXADECIMAL){

line.add(addZeros(Integer.toString(i.getDataUnsigned(), 16), 4) );}

}else{

line.add(Integer.toString(i.getAddressLocation()));line.add("");line.add("");if(base == Base.DECIMAL){

line.add(Integer.toString(i.getDataSigned()));}else if(base == Base.BINARY){

line.add(addZeros(Integer.toString(i.getDataUnsigned(), 2), 16) );}else if(base == Base.HEXADECIMAL){

line.add(addZeros(Integer.toString(i.getDataUnsigned(), 16),4) );}

}tModel.addRow(line);mModel.addRow(line);//System.out.println(i);

}pTableRenderer = new ColorCellRenderer(pTable);memoriaTableRenderer = new ColorCellRenderer(memoriaTable);pTable.getColumnModel().getColumn(3).setCellRenderer(pTableRenderer);pTable.getColumnModel().getColumn(2).setCellRenderer(pTableRenderer);pTable.getColumnModel().getColumn(1).setCellRenderer(pTableRenderer);pTable.getColumnModel().getColumn(0).setCellRenderer(pTableRenderer);memoriaTable.getColumnModel().getColumn(3).setCellRenderer(memoriaTableRenderer);memoriaTable.getColumnModel().getColumn(2).setCellRenderer(memoriaTableRenderer);memoriaTable.getColumnModel().getColumn(1).setCellRenderer(memoriaTableRenderer);memoriaTable.getColumnModel().getColumn(0).setCellRenderer(memoriaTableRenderer);

}

/** * @brief Inicializa la memoria del computador con cierto código * @param codeArray Código a depurar */public void setDebugCode(ArrayList<Instruction> codeArray, File file){

actionRestart();debugFile = file;execTrace = new Trace(debugFile);computer.setMemoryMap(codeArray);updateJTableModel();selectNextInstructionInMemoryNearP(0);

}

/** * Constructor de la vista depuración. */public DebugViewManager(){

super();

//Inicializar algunas variables de la clase.isCheckBoxSelected = executeSemisteps = false;execTrace = null;debugFile = null;

143

Page 155: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

pTableRenderer = null;memoriaTableRenderer = null;startTime = -1;nextTime = -1;instructionTimer = new Timer("Timer");changesTimer = new Timer("Changes");instructionTask = null;//runMode = false;runTo = -1;setOrientation(JSplitPane.HORIZONTAL_SPLIT);setResizeWeight(0);setDividerLocation(630);

//Queremos que la barra de separación no se pueda moveraddPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {

@Overridepublic void propertyChange(PropertyChangeEvent pce) { // do here

setDividerLocation(630);}});

//Inicializamos el computadorcomputer = new VirtualComputer();computer.setListener(this);//Período inicial de 500msperiod = 500L;

//JSplitPlane que contiene el visor de memoria entorno a P y el visor general de memoriaJSplitPane memoryViewers= new JSplitPane();memoryViewers.setOrientation(JSplitPane.VERTICAL_SPLIT);memoryViewers.setDividerLocation(300);setRightComponent(memoryViewers);

JTabbedPane nearPViewer = new JTabbedPane(JTabbedPane.TOP);nearPViewer.setMinimumSize(new Dimension(417, 300));JScrollPane scrollNearP = new JScrollPane();nearPViewer.addTab("Memoria entorno a P", null, scrollNearP, null);

JTabbedPane allMemoryViewer = new JTabbedPane(JTabbedPane.TOP);JScrollPane scrollAllMemory = new JScrollPane();allMemoryViewer.addTab("Visor de Memoria", null, scrollAllMemory, null);

memoryViewers.setLeftComponent(nearPViewer);memoryViewers.setRightComponent(allMemoryViewer);

//Tabla de memoria del visor de memoria entorno a PpTable = new JTable(new DefaultTableModel(){

/** * */private static final long serialVersionUID = 1L;

public boolean isCellEditable(int rowIndex, int colIndex) { return false;}

});

//El usuario solo debería poder seleccionar una fila/instrucción.ListSelectionModel psm = pTable.getSelectionModel();psm.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);TableListener tl = new TableListener();psm.addListSelectionListener(tl);

scrollNearP.setViewportView(pTable);

//Aquí inicializamos todos los campos de los registros

textFieldA = new FlashyTextField("0", changesTimer);textFieldA.setColumns(12);textFieldA.setHorizontalAlignment(JTextField.RIGHT);textFieldA.setEditable(false);

textFieldP = new FlashyTextField("0", changesTimer);textFieldP.setColumns(8);textFieldP.setHorizontalAlignment(JTextField.RIGHT);textFieldP.setEditable(false);

textFieldS = new FlashyTextField("0", changesTimer);textFieldS.setColumns(8);textFieldS.setHorizontalAlignment(JTextField.RIGHT);textFieldS.setEditable(false);

textFieldI = new FlashyTextField("0", changesTimer);textFieldI.setColumns(8);textFieldI.setHorizontalAlignment(JTextField.RIGHT);textFieldI.setEditable(false);

textFieldT = new FlashyTextField("0", changesTimer);textFieldT.setColumns(12);

144

Page 156: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

textFieldT.setHorizontalAlignment(JTextField.RIGHT);textFieldT.setEditable(false);

textFieldE = new FlashyTextField("0", changesTimer);textFieldE.setColumns(12);textFieldE.setHorizontalAlignment(JTextField.RIGHT);textFieldE.setEditable(false);

textFieldCO = new FlashyTextField("0000", changesTimer);textFieldCO.setColumns(3);textFieldCO.setHorizontalAlignment(JTextField.RIGHT);textFieldCO.setEditable(false);

textFieldMD = new FlashyTextField("0", changesTimer);textFieldMD.setColumns(1);textFieldMD.setHorizontalAlignment(JTextField.RIGHT);textFieldMD.setEditable(false);

//tabbedMonitor es la pantalla de la consolaJTabbedPane tabbedMonitor = new JTabbedPane(JTabbedPane.TOP);JScrollPane scrollMonitor = new JScrollPane();tabbedMonitor.addTab("Monitor", null, scrollMonitor, null);consolaPane = new JTextPane();consolaPane.setEditable(false);//Con esto el enter será sólo un carácter raro sin efectoconsolaPane.setFocusTraversalKeysEnabled(false);

consolaListener = new ConsoleKeyListener();consolaPane.addKeyListener(consolaListener);

scrollMonitor.setViewportView(consolaPane);

//A continuación cargamos todos los iconos que necesitamosjava.net.URL imageURL = Emulator.class.getResource("images/bus.png");ImageIcon icon = new ImageIcon(imageURL);JLabel busLabel = new JLabel();busLabel.setIcon(icon);

imageURL = Emulator.class.getResource("images/ALU.png");icon = new ImageIcon(imageURL);JLabel aluLabel = new JLabel();aluLabel.setIcon(icon);

imageURL = Emulator.class.getResource("images/sBus.png");icon = new ImageIcon(imageURL);JLabel sBusLabel = new JLabel();sBusLabel.setIcon(icon);

imageURL = Emulator.class.getResource("images/keyboard-icon2.png");icon = new ImageIcon(imageURL);JLabel keyboardButton = new JLabel();keyboardButton.setIcon(icon);

//Los siguientes iconos no serán visibles, son un hack para poder pintar correctamente las flechas//que conectan los registrosimageURL = Emulator.class.getResource("images/point.png");icon = new ImageIcon(imageURL);JLabel point = new JLabel();point.setIcon(icon);JLabel point2 = new JLabel();point2.setIcon(icon);point2.setVisible(false);JLabel point3 = new JLabel();point3.setIcon(icon);point3.setVisible(false);JLabel point4 = new JLabel();point4.setIcon(icon);point4.setVisible(false);JLabel point5 = new JLabel();point5.setIcon(icon);point5.setVisible(false);

//Estos puntos son las válvulas de control de flujo que manejan las señales del computadorimageURL = Emulator.class.getResource("images/punto.png");icon = new ImageIcon(imageURL);JLabel punto1 = new JLabel();punto1.setIcon(icon);JLabel punto2 = new JLabel();punto2.setIcon(icon);JLabel punto3 = new JLabel();punto3.setIcon(icon);JLabel punto4 = new JLabel();punto4.setIcon(icon);JLabel punto5 = new JLabel();punto5.setIcon(icon);JLabel punto6 = new JLabel();punto6.setIcon(icon);JLabel punto7 = new JLabel();punto7.setIcon(icon);JLabel punto8 = new JLabel();

145

Page 157: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

punto8.setIcon(icon);JLabel punto9 = new JLabel();punto9.setIcon(icon);JLabel punto10 = new JLabel();punto10.setIcon(icon);JLabel punto11 = new JLabel();punto11.setIcon(icon);JLabel punto12 = new JLabel();punto12.setIcon(icon);JLabel punto13 = new JLabel();punto13.setIcon(icon);JLabel punto14 = new JLabel();punto14.setIcon(icon);//JButton keyboardButton = new JButton("Abrir Teclado Virtual");

//Etiquetas de los registrosJLabel eLabel = new JLabel("E");JLabel tLabel = new JLabel("T");JLabel aLabel = new JLabel("A");JLabel pLabel = new JLabel("P");JLabel sLabel = new JLabel("S");JLabel iLabel = new JLabel("I");JLabel mLabel = new JLabel("M");JLabel ssLabel = new JLabel("S");

coLabel = new JLabel("CO");mdLabel = new JLabel("MD");dLabel = new JLabel("D");

//Etiquetas de las señalesetLabel = new FlashySignal("ET", changesTimer);stLabel = new FlashySignal("ST", changesTimer);eeLabel = new FlashySignal("EE", changesTimer);seLabel = new FlashySignal("SE", changesTimer);escpLabel = new FlashySignal("ESCP", changesTimer);leetLabel = new FlashySignal("LEET", changesTimer);eaLabel = new FlashySignal("EA", changesTimer);saLabel = new FlashySignal("SA", changesTimer);eoLabel = new FlashySignal("EO", changesTimer);sumaLabel = new FlashySignal("SUMA", changesTimer);resaLabel = new FlashySignal("RESA", changesTimer);multaLabel = new FlashySignal("MULTA", changesTimer);incpLabel = new FlashySignal("INCP", changesTimer);spLabel = new FlashySignal("SP", changesTimer);epLabel = new FlashySignal("EP", changesTimer);sdLabel = new FlashySignal("SD", changesTimer);eiLabel = new FlashySignal("EI", changesTimer);esLabel = new FlashySignal("ES", changesTimer);lecmLabel = new FlashySignal("LECM", changesTimer);escmLabel = new FlashySignal("ESCM", changesTimer);divaLabel = new FlashySignal("DIVA", changesTimer);modaLabel = new FlashySignal("MODA", changesTimer);

//computerGraphics es el panel donde se dibujará el esquema del computador//Es de tipo ConnectorContainer para poder pintar flechas fácilmente en élConnectorContainer computerGraphics = new ConnectorContainer();computerGraphics.setMinimumSize(new Dimension(630, 400));computerGraphics.setMaximumSize(new Dimension(630, Short.MAX_VALUE));setLeftComponent(computerGraphics);

//Layout del computadorGroupLayout gl_menu2 = new GroupLayout(computerGraphics);gl_menu2.setHorizontalGroup(

gl_menu2.createParallelGroup(Alignment.LEADING).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(10, 10)

.addGroup(gl_menu2.createParallelGroup(Alignment.LEADING).addGroup(gl_menu2.createSequentialGroup()

.addComponent(aLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(10, 10)

.addComponent(textFieldA, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(72, 72)

.addComponent(punto7, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(eaLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(40, 40)

.addComponent(aluLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addGroup(gl_menu2.createParallelGroup(Alignment.LEADING)

.addComponent(sumaLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(resaLa

146

Page 158: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

bel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(multaL

abel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(divaLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(modaLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

)).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(54, 54)

.addComponent(point, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(26, 26)

.addComponent(punto8, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(saLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(23, 23)

.addComponent(punto9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(eoLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(30, 30)

.addComponent(mLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

)).addContainerGap(90, 90).addGroup(gl_menu2.createParallelGroup(Alignment.LEADING)

.addGroup(gl_menu2.createSequentialGroup().addComponent(pLabel,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addContainerGap(10, 10).addComponent(textFieldP,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addContainerGap(10, 10).addComponent(incpLabel,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addGroup(gl_menu2.createSequentialGroup()

.addComponent(epLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(punto10, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(25, 25)

.addComponent(punto11, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(spLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(ssLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(42, 42)

.addComponent(esLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createSequentialGroup()

.addComponent(sBusLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(10, 10)

.addComponent(punto12, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(10, 10)

.addComponent(textFieldS, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(10, 10)

.addComponent(sLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(24, 24)

.addComponent(point4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(70, 70)

.addComponent(sdLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(punto13, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createSequentialGroup()

.addComponent(coLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

147

Page 159: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

.addContainerGap(15, 15)

.addComponent(mdLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(15, 15)

.addComponent(dLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createSequentialGroup()

.addComponent(textFieldCO, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(1, 1)

.addComponent(textFieldMD, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(1, 1)

.addComponent(textFieldI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(15, 15)

.addComponent(iLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(280, 280)

.addComponent(lecmLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(point2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(280, 280)

.addComponent(escmLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(point3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(80, 80)

.addComponent(eiLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(punto14, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

))

).addComponent(busLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,

GroupLayout.PREFERRED_SIZE).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(10, 10)

.addGroup(gl_menu2.createParallelGroup(Alignment.LEADING).addGroup(gl_menu2.createSequentialGroup()

.addGroup(gl_menu2.createParallelGroup(Alignment.LEADING)

.addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(20, 20)

.addComponent(eeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(punto3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(40, 40)

.addComponent(seLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(punto4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createSeque

ntialGroup().addCompon

ent(eLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addContai

nerGap(10, 10).addCompon

ent(textFieldE, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))

).addContainerGap(280, 280).addGroup(gl_menu2.createParallelGroup(A

lignment.LEADING).addGroup(

gl_menu2.createSequentialGroup()

.addComponent(etLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

148

Page 160: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

.addComponent(punto1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(40, 40)

.addComponent(stLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(punto2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addGroup(

gl_menu2.createSequentialGroup()

.addComponent(tLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(10, 10)

.addComponent(textFieldT, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(10, 10)

.addComponent(point5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))

)).addGroup(gl_menu2.createSequentialGroup()

.addGroup(gl_menu2.createSequentialGroup().addCompon

ent(leetLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addCompon

ent(punto6, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))

.addContainerGap(5, 5)

.addGroup(gl_menu2.createParallelGroup(Alignment.LEADING)

.addGroup(gl_menu2.createSequentialGroup()

.addComponent(escpLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addContainerGap(20, 20)

.addComponent(punto5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addComponent(tabbedMonitor,

0, 400, 400))

).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(20, 20)

.addComponent(keyboardButton, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

))

));

gl_menu2.setVerticalGroup(gl_menu2.createSequentialGroup().addContainerGap(10, 10).addGroup(gl_menu2.createParallelGroup(Alignment.LEADING)

.addGroup(gl_menu2.createSequentialGroup().addContainerGap(7, 7).addGroup(gl_menu2.createParallelGroup(Alignment.LEADING)

.addComponent(aLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(textFieldA, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addContainerGap(10, 10).addGroup(gl_menu2.createParallelGroup(Alignment.CENTER)

.addComponent(punto7, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(eaLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addContainerGap(10, 10).addGroup(gl_menu2.createParallelGroup(Alignment.LEADING)

.addComponent(aluLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addGroup(gl_menu2.createSequentialGroup()

.addComponent(sumaLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(resaLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(multaLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(divaLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(modaLa

149

Page 161: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

bel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))

).addContainerGap(20, 20).addComponent(point, GroupLayout.PREFERRED_SIZE,

GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addContainerGap(10, 10).addGroup(gl_menu2.createParallelGroup(Alignment.CENTER)

.addComponent(punto8, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(saLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(punto9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(eoLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(mLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

)).addGroup(gl_menu2.createSequentialGroup()

.addGroup(gl_menu2.createParallelGroup(Alignment.CENTER).addComponent(pLabel,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(textFieldP,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(incpLabel,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))

.addContainerGap(10, 10)

.addGroup(gl_menu2.createParallelGroup(Alignment.CENTER).addComponent(epLabel,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(punto10,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(punto11,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(spLabel,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addGroup(gl_menu2.createSequentialGroup

().addContainerGap(15,

15).addComponent(ssLabe

l, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addComponent(esLabel,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))

.addGroup(gl_menu2.createParallelGroup(Alignment.CENTER).addComponent(sBusLabel,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(punto12,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(textFieldS,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(sLabel,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(point4,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addContainerGap(5, 5).addGroup(gl_menu2.createParallelGroup(Alignment.CENTER)

.addComponent(sdLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(punto13, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addContainerGap(1, 1).addGroup(gl_menu2.createParallelGroup(Alignment.LEADING)

.addComponent(coLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(mdLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(dLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createParallelGroup(Alignment.LEADING)

.addComponent(textFieldCO, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(textFieldMD, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(textFieldI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(iLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addGroup(gl_menu2.createParallelGroup(Alignment.CENTER)

.addComponent(lecmLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

150

Page 162: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

.addComponent(point2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

)

.addGroup(gl_menu2.createParallelGroup(Alignment.CENTER).addComponent(escmLabel,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(point3,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addGroup(gl_menu2.createParallelGroup(Alignment.CENTER)

.addComponent(eiLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(punto14, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addContainerGap(2, 2)

)).addComponent(busLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,

GroupLayout.PREFERRED_SIZE)

.addGroup(gl_menu2.createSequentialGroup().addContainerGap(10, 10).addGroup(gl_menu2.createParallelGroup(Alignment.CENTER)

.addGroup(gl_menu2.createSequentialGroup().addGroup(gl_menu2.createParallelGroup(A

lignment.CENTER).addComponent(eeLabe

l, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(punto3

, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(seLabe

l, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(punto4

, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addContainerGap(10, 10).addGroup(gl_menu2.createParallelGroup(A

lignment.LEADING).addComponent(eLabel

, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(textFi

eldE, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))

).addGroup(gl_menu2.createSequentialGroup()

.addGroup(gl_menu2.createParallelGroup(Alignment.CENTER)

.addComponent(etLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(punto1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(stLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(punto2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

).addContainerGap(10, 10).addGroup(gl_menu2.createParallelGroup(A

lignment.CENTER).addComponent(tLabel

, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(textFi

eldT, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(point5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

))

)).addGroup(gl_menu2.createParallelGroup(Alignment.LEADING)

.addGroup(gl_menu2.createSequentialGroup().addContainerGap(10, 10).addGroup(gl_menu2.createParallelGroup(Alignment.CENTER)

.addComponent(leetLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addComponent(punto6, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

)).addGroup(gl_menu2.createSequentialGroup()

.addContainerGap(10, 10)

.addGroup(gl_menu2.createParallelGroup(Alignment.CENTER).addComponent(escpLabel,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(punto5,

GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addContainerGap(10, 10).addComponent(tabbedMonitor, 0, 300, 300)

151

Page 163: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

)).addContainerGap(10, 10).addComponent(keyboardButton, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,

GroupLayout.PREFERRED_SIZE)

);

computerGraphics.setLayout(gl_menu2); //Lista de flechas del esquema del computador ArrayList<JConnector> con = new ArrayList<JConnector>(); con.add( new JConnector(etLabel ,punto1, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto1 ,textFieldT, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto1 ,busLabel, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add( new JConnector(stLabel ,punto2, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto2 ,textFieldT, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add( new JConnector(punto2 ,busLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); con.add( new JConnector(sLabel ,point4, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK)); ///////

con.add( new JConnector(eeLabel ,punto3, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto3 ,textFieldE, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto3 ,busLabel, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add( new JConnector(seLabel ,punto4, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto4 ,textFieldE, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add( new JConnector(punto4 ,busLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); //////////

con.add( new JConnector(escpLabel ,punto5, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto5 ,textFieldE, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto5 ,tabbedMonitor, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); ////////

con.add( new JConnector(punto6 ,textFieldE, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto6 ,keyboardButton, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); /////////

con.add( new JConnector(eaLabel ,punto7, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto7 ,aluLabel, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto7 ,textFieldA, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); con.add( new JConnector(resaLabel ,aluLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK)); ///////

con.add( new JConnector(saLabel ,punto8, ConnectLine.LINE_ARROW_DEST,

152

Page 164: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto8 ,textFieldA, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto8 ,busLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add( new JConnector(point ,punto8, ConnectLine.LINE_ARROW_NONE, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK)); con.add( new JConnector(point ,aluLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); ////////

con.add( new JConnector(eoLabel ,punto9, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto9 ,busLabel, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto9 ,aluLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); ////////

con.add( new JConnector(sumaLabel ,aluLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(multaLabel ,aluLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(divaLabel ,aluLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(modaLabel ,aluLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK)); /////

con.add( new JConnector(incpLabel ,textFieldP, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK)); //// con.add( new JConnector(epLabel ,punto10, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto10 ,textFieldP, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto10 ,sBusLabel, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); ///////

con.add( new JConnector(spLabel ,punto11, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto11 ,textFieldP, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto11 ,sBusLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); //////

con.add( new JConnector(esLabel ,punto12, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto12 ,sBusLabel, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto12 ,textFieldS, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); //////

con.add( new JConnector(sdLabel ,punto13, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto13 ,textFieldI, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto13 ,sBusLabel, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); //////

153

Page 165: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

con.add( new JConnector(eiLabel ,punto14, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(punto14 ,busLabel, ConnectLine.LINE_ARROW_SOURCE, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK));

con.add(new JConnector(punto14 ,textFieldI, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_VERTICAL, Color.BLACK)); //////

con.add( new JConnector(lecmLabel ,point2, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(escmLabel ,point3, ConnectLine.LINE_ARROW_DEST, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK));

con.add( new JConnector(textFieldT ,point5, ConnectLine.LINE_ARROW_BOTH, ConnectLine.LINE_TYPE_RECT_HORIZONTAL, Color.BLACK)); ////// //Añadimos las flechas al panel que contiene el esquema del computador computerGraphics.addConnectors(con);

Action actionLimpiarConsola = new AbstractAction("Limpiar", null) {private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

consolaPane.setText(""); }};

//menú que sirve para limpiar la consolaJPopupMenu popup = new JPopupMenu();popup.add(actionLimpiarConsola);MouseListener popupListener = new PopupListener(popup);consolaPane.addMouseListener(popupListener);

memoriaTable = new JTable();memoriaTable.setModel(new DefaultTableModel(){

/** * */private static final long serialVersionUID = 1L;

public boolean isCellEditable(int rowIndex, int colIndex) { return false;}

});//Los usuarios solo deberían ser capaces de seleccionar una fila/instrucciónListSelectionModel msm = memoriaTable.getSelectionModel();msm.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

scrollAllMemory.setViewportView(memoriaTable);

//Actualiza los registros y señales del computador en la interfaz gráficasetRegistersBase(Base.DECIMAL);

//El buffer inicial no contiene datosinputBuffer = null;

}

@Overridepublic void writeNumberToScreen() {

addConsoleOutput("" + computer.getState().getE());

}

@Overridepublic void stateChanged() {

//Recolectamos el estado del computadorComputerState c = computer.getState();Color myColor = null;if(c.getSemiState() == VirtualComputer.First_Semistep){

myColor = new Color(0, 184, 245);}else{

myColor = new Color(245, 0, 0);}///////////////////////////////////////Actualizamos el estado de todas las señalesif(c.getSignal(ComputerSignal.ET) == true){

etLabel.flash(myColor);}else{

154

Page 166: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

etLabel.restart();}if(c.getSignal(ComputerSignal.ST) == true){

stLabel.flash(myColor);}else{

stLabel.restart();}if(c.getSignal(ComputerSignal.EE) == true){

eeLabel.flash(myColor);}else{

eeLabel.restart();}if(c.getSignal(ComputerSignal.SE) == true){

seLabel.flash(myColor);}else{

seLabel.restart();}if(c.getSignal(ComputerSignal.ESCP) == true){

escpLabel.flash(myColor);}else{

escpLabel.restart();}if(c.getSignal(ComputerSignal.LEET) == true){

leetLabel.flash(myColor);}else{

leetLabel.restart();}if(c.getSignal(ComputerSignal.EA) == true){

eaLabel.flash(myColor);}else{

eaLabel.restart();}if(c.getSignal(ComputerSignal.SA) == true){

saLabel.flash(myColor);}else{

saLabel.restart();}if(c.getSignal(ComputerSignal.EO) == true){

eoLabel.flash(myColor);}else{

eoLabel.restart();}if(c.getSignal(ComputerSignal.SUMA) == true){

sumaLabel.flash(myColor);}else{

sumaLabel.restart();}if(c.getSignal(ComputerSignal.RESA) == true){

resaLabel.flash(myColor);}else{

resaLabel.restart();}if(c.getSignal(ComputerSignal.MULTA) == true){

multaLabel.flash(myColor);}else{

multaLabel.restart();}if(c.getSignal(ComputerSignal.DIVA) == true){

155

Page 167: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

divaLabel.flash(myColor);}else{

divaLabel.restart();}if(c.getSignal(ComputerSignal.MODA) == true){

modaLabel.flash(myColor);}else{

modaLabel.restart();}if(c.getSignal(ComputerSignal.INCP) == true){

incpLabel.flash(myColor);}else{

incpLabel.restart();}if(c.getSignal(ComputerSignal.EP) == true){

epLabel.flash(myColor);}else{

epLabel.restart();}if(c.getSignal(ComputerSignal.SP) == true){

spLabel.flash(myColor);}else{

spLabel.restart();}if(c.getSignal(ComputerSignal.ES) == true){

esLabel.flash(myColor);}else{

esLabel.restart();}if(c.getSignal(ComputerSignal.SD) == true){

sdLabel.flash(myColor);}else{

sdLabel.restart();}if(c.getSignal(ComputerSignal.EI) == true){

eiLabel.flash(myColor);}else{

eiLabel.restart();}if(c.getSignal(ComputerSignal.ESCM) == true){

escmLabel.flash(myColor);}else{

escmLabel.restart();}if(c.getSignal(ComputerSignal.LECM) == true){

lecmLabel.flash(myColor);}else{

lecmLabel.restart();}if(c.hasRegisterChanged(ComputerRegister.A) == true){

textFieldA.flash(myColor);}else {

textFieldA.restart();}if(c.hasRegisterChanged(ComputerRegister.E) == true){

textFieldE.flash(myColor);}else {

textFieldE.restart();}

156

Page 168: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

if(c.hasRegisterChanged(ComputerRegister.T) == true){

textFieldT.flash(myColor);}else {

textFieldT.restart();}if(c.hasRegisterChanged(ComputerRegister.I) == true){

textFieldI.flash(myColor);if(base == Base.BINARY){

textFieldCO.flash(myColor);textFieldMD.flash(myColor);

}else{

textFieldCO.restart();textFieldMD.restart();

}}else {

textFieldI.restart();textFieldCO.restart();textFieldMD.restart();

}if(c.hasRegisterChanged(ComputerRegister.S) == true){

textFieldS.flash(myColor);}else {

textFieldS.restart();}if(c.hasRegisterChanged(ComputerRegister.P) == true){

textFieldP.flash(myColor);}else {

textFieldP.restart();}if(c.hasChangedMemory() == true){

pTableRenderer.flash(c.getChangedMemory());memoriaTableRenderer.flash(c.getChangedMemory());

}else{

pTableRenderer.restart();memoriaTableRenderer.restart();

}//las señales han sido leidas//c.resetSignalsRegisters();///////////////////////////////////////Actualizamos la posición de memoria seleccionada en el visor de memoria entorno a PselectNextInstructionInMemoryNearP(c.getP());

//Actualizamos los registros, dependiendo de la base usadatry{if(base == Base.BINARY){

Instruction i = new Instruction();i.setInstructionSigned(c.getA());textFieldA.setText(addZeros(Integer.toString(i.getDataUnsigned(), 2), 16));i.setInstructionSigned(c.getP());textFieldP.setText(addZeros(Integer.toString(i.getDataUnsigned(), 2), 11));i.setInstructionSigned(c.getS());textFieldS.setText(addZeros(Integer.toString(i.getDataUnsigned(), 2), 11));i.setInstructionSigned(c.getI());String s = addZeros(Integer.toString(i.getDataUnsigned(), 2), 16);String co = s.substring(0, 4);String md = s.substring(4, 5);String d = s.substring(5);textFieldCO.setText(co);textFieldMD.setText(md);textFieldI.setText(d);i.setInstructionSigned(c.getT());textFieldT.setText(addZeros(Integer.toString(i.getDataUnsigned(), 2), 16));i.setInstructionSigned(c.getE());textFieldE.setText(addZeros(Integer.toString(i.getDataUnsigned(), 2), 16));

}else if(base == Base.DECIMAL){

textFieldA.setText(Integer.toString(c.getA(), 10));textFieldP.setText(Integer.toString(c.getP(), 10));textFieldS.setText(Integer.toString(c.getS(), 10));textFieldI.setText(Integer.toString(c.getI(), 10));textFieldT.setText(Integer.toString(c.getT(), 10));textFieldE.setText(Integer.toString(c.getE(), 10));textFieldCO.setText("");textFieldMD.setText("");

}else if(base == Base.HEXADECIMAL)

157

Page 169: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

{Instruction i = new Instruction();i.setInstructionSigned(c.getA());textFieldA.setText(addZeros(Integer.toString(i.getDataUnsigned(), 16), 4));i.setInstructionSigned(c.getP());textFieldP.setText(addZeros(Integer.toString(i.getDataUnsigned(), 16), 4));i.setInstructionSigned(c.getS());textFieldS.setText(addZeros(Integer.toString(i.getDataUnsigned(), 16), 4));i.setInstructionSigned(c.getI());textFieldI.setText(addZeros(Integer.toString(i.getDataUnsigned(), 16), 4));i.setInstructionSigned(c.getT());textFieldT.setText(addZeros(Integer.toString(i.getDataUnsigned(), 16), 4));i.setInstructionSigned(c.getE());textFieldE.setText(addZeros(Integer.toString(i.getDataUnsigned(), 16), 4));textFieldCO.setText("");textFieldMD.setText("");

}}catch (Exception excep){

}

}/** * Añade ceros a la cadena 's' hasta que dicha cadena tenga una longitud 'a' * @param s * @param a * @return */String addZeros(String s, int a){

String r = "";int b = a - s.length();if (b > 0){

for(int j = 0; j < b; j++){

r = r + "0";}

}r = r + s;return r;

}

@Overridepublic void memoryChanged(Instruction i) {

try {changeMemoryAddress(i);

}catch(Exception e){

// TODO Auto-generated method stub}

}

@Overridepublic void writeCharacterToScreen() {

// TODO Auto-generated method stubchar c = (char)computer.getState().getE();addConsoleOutput(Character.toString(c));

}

@Overridepublic void itemStateChanged(ItemEvent itemEvent) {

int state = itemEvent.getStateChange(); if (state == ItemEvent.SELECTED) { isCheckBoxSelected = true; System.out.println("SELECTED"); } else if (state == ItemEvent.DESELECTED) { isCheckBoxSelected = false; System.out.println("DESELECTED"); }

}

}

158

Page 170: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.11 ProjectFile.java package xenon;

import java.io.File;

import javax.swing.tree.DefaultMutableTreeNode;

/** * * @brief Define un fichero que pertenece a un proyecto. * */public class ProjectFile{

public DefaultMutableTreeNode fnode; //Nodo perteneciente al fichero en el árbol de ficherospublic enum FileType {BINARY, TEXT, CODE}; //Tipos de fichero; Código binario, código ensamblador o texto.public FileType type; //Tipo de ficheropublic File file; //Ruta del fichero en el sistema de archivospublic Project project; //Proyecto al que pertenece el fichero

/** * @brief Devuelve el nombre del fichero en una cadena. */public String toString(){

String s = "";if(file != null){

s = file.getName();}return s;

}

/** * @brief Constructor. * Las extensiones reconocidas para los ficheros de un proyecto * son ls2 (código) y ece (binario). El resto de archivos es tratado * como texto. */public ProjectFile(File f, Project p){

file = f;String arg1 = f.getName().toLowerCase();if(arg1.lastIndexOf('.')>0)

{ // Obtener el último índice del carácter '.' int lastIndex = arg1.lastIndexOf('.'); // Obtener extensión String str = arg1.substring(lastIndex); // Comprobar la extensión del fichero if(str.equals(".ls2")) { type = FileType.CODE; } else if(str.equals(".ece")) { type = FileType.BINARY; } else { type = FileType.TEXT; } }

project = p;}/** * @brief Asigna 'no' como nodo de este fichero en el árbol de proyectos. * @param no */public void setNode(DefaultMutableTreeNode no){

fnode = no;}

}

159

Page 171: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.12 TabsManager.java package xenon;

import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.util.ArrayList;

import javax.swing.JFileChooser;import javax.swing.JOptionPane;import javax.swing.JTabbedPane;import javax.swing.JTextArea;

/** * @brief Clase gestora de las pestañas. * */public class TabsManager{

private JTabbedPane tabbedFilePane; //Panel que contiene las pestañas

/** * @brief Devuelve el panel de pestañas * @return */public JTabbedPane getTabbedPane(){

return tabbedFilePane;}/** * @brief Constructor * @param tab */public TabsManager(JTabbedPane tab){

tabbedFilePane = tab;}

/** * @brief Busca una pestaña que contenga el fichero pfile * @param pfile * @return null si ninguna pestaña contiene pfile, en caso contrario devuelve dicha pestaña */public Tab searchTab(ProjectFile pfile){

//TODO:Tab tt = null;

boolean bFlag = true;for(int i = 0, n = tabbedFilePane.getTabCount(); i < n && bFlag; i++){

Tab t = (Tab)tabbedFilePane.getComponentAt(i);

if(t.pFile == pfile){

bFlag = false;tt = t;break;

}}return tt;

}

/** * Elimina la pestaña sin preguntar si quieres guardar el fichero. * @param t */public void dontAskAndRemoveTab(Tab t){

tabbedFilePane.remove(t);}

/** * @brief Si el fichero ha sido modificado, pregunta si quieres guardarlo. Entonces lo cierra. * @param t */public void askAndRemoveTab(Tab t){

int i = tabbedFilePane.indexOfComponent(t); if (i != -1) { if(t.isModified()) { Object[] options = {"Si", "No", "Cancelar"}; int n = JOptionPane.showOptionDialog(null, "'" + t.pFile.file.getName() + "'" + " ha sido modificado. ¿Desea guardar los cambios realizados?", "Guardar Fichero", JOptionPane.YES_NO_CANCEL_OPTION,

160

Page 172: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

JOptionPane.QUESTION_MESSAGE, null, options, options[0]); if(n == JOptionPane.YES_OPTION) { saveTabTo(t, t.pFile.file.getPath()); tabbedFilePane.remove(t); } else if(n == JOptionPane.NO_OPTION) { tabbedFilePane.remove(t); } else if(n == JOptionPane.CANCEL_OPTION) { //Do nothing! } } else { tabbedFilePane.remove(t); } }

}

/** * @brief Elimina una pestaña a partir de su etiqueta ButtonTabComponent, * que contiene el nombre del archivo y el botón en forma de X que sirve para cerrarla. * @param ct */public void removeTab(ButtonTabComponent ct){

int i = tabbedFilePane.indexOfTabComponent(ct);Tab t = (Tab)tabbedFilePane.getComponentAt(i);askAndRemoveTab(t);

}

/** * @brief Este método añadirá una pestaña al panel de pestañas si no existe una pestaña con el fichero * pfile. En otro caso seleccionará y mostrará dicha pestaña. */public void addTab(ProjectFile pfile){

//Comprobamos si existe una pestaña con ese ficheroboolean bFlag = true;for(int i = 0, n = tabbedFilePane.getTabCount(); i < n && bFlag; i++){

Tab t = (Tab)tabbedFilePane.getComponentAt(i);

if(t.pFile == pfile) //La pestaña existe, la seleccionamos y mostramos{

bFlag = false;tabbedFilePane.setSelectedIndex(i);

}}if(bFlag == true) { //No existe, luego añadimos la pestaña

JTextArea textArea = new JTextArea();Tab t = new Tab(textArea, pfile);tabbedFilePane.addTab(null, t);tabbedFilePane.setSelectedComponent(t);

int index = tabbedFilePane.indexOfComponent(t);ButtonTabComponent btc = new ButtonTabComponent(this,pfile.file.getName());t.setLabel(btc.getLabel());tabbedFilePane.setTabComponentAt(index,btc);

}}

/** * @brief Guarda el fichero de una pestaña t en la ruta path. * @param t * @param path */private void saveTabTo(Tab t, String path){

File fileName = new File(path);if (fileName != null){

if(t.pFile.type == ProjectFile.FileType.CODE || t.pFile.type == ProjectFile.FileType.TEXT){

System.out.println("Guardando " + path + " ...");try {

BufferedWriter outFile = new BufferedWriter(new FileWriter(fileName)); outFile.write(t.textArea.getText()); //put in textfile outFile.close();

}catch (IOException ex) {

}} else if(t.pFile.type == ProjectFile.FileType.BINARY)

161

Page 173: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

{

}}

}

/** * @brief Guarda el fichero de la pestaña actualmente seleccionado. */public void saveCurrentlySelectedTab(){

if(tabbedFilePane.getTabCount() > 0){

Tab t = (Tab)tabbedFilePane.getComponentAt(tabbedFilePane.getSelectedIndex());saveTabTo(t, t.pFile.file.getPath());t.setModified(false);

}}

/** * @brief Devuelve la pestaña actualmente seleccionada, o null si no existe ninguna pestaña. * @return */public Tab getCurrentlySelectedTab(){

int i = tabbedFilePane.getSelectedIndex();return (i >= 0)? (Tab)tabbedFilePane.getComponentAt(i): null;

}

/** * @brief Crea un diálogo que pregunta dónde se quiere guardar el texto de la actual pestaña, y lo guarda. */public void saveCurrentlySelectedTabAs(){

if(tabbedFilePane.getTabCount() > 0){

Tab t = (Tab)tabbedFilePane.getComponentAt(tabbedFilePane.getSelectedIndex());

JFileChooser SaveAs = new JFileChooser();int actionDialog = SaveAs.showDialog(null, "Guardar Como...");if(actionDialog == JFileChooser.APPROVE_OPTION){

saveTabTo(t, SaveAs.getSelectedFile().getPath());}

}}

/** * @brief Guarda los cambios realizados en los ficheros de todas las pestañas. */public void saveAllTabs(){

for(int i = 0, n = tabbedFilePane.getTabCount(); i < n; i++){

Tab t = (Tab)tabbedFilePane.getComponentAt(i);saveTabTo(t, t.pFile.file.getPath());t.setModified(false);

}}

/** * @brief Comprueba si el fichero ha sido modificado y pregunta al usuario si quiere guardar los cambios. */public void saveIfModified(ProjectFile codeToDebug){

boolean bFlag = true;for(int i = 0, n = tabbedFilePane.getTabCount(); i < n && bFlag; i++){

Tab t = (Tab)tabbedFilePane.getComponentAt(i);if(t.pFile == codeToDebug && t.isModified()){

bFlag = false;Object[] options = {"Si",

"No"};int ss = JOptionPane.showOptionDialog(null,"El fichero " +codeToDebug.file.getName() +" ha sido modificado. ¿Desea guardar los cambios realizados?", "Guardar fichero",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE,null,options,options[0]);

if(ss == JOptionPane.YES_OPTION){

saveTabTo(t, t.pFile.file.getPath());t.setModified(false);

}}

}

162

Page 174: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

}

/** * Cierra todas las pestañas del proyecto p. * @param p * @return */public boolean closeAllTabsOfProject(Project p){

if (p == null){return false;

}boolean result = true;ArrayList<Tab> list = new ArrayList<Tab>();boolean modified = false;for(int i = 0, n = tabbedFilePane.getTabCount(); i < n ; i++){

Tab t = (Tab)tabbedFilePane.getComponentAt(i);//System.out.println(t);if(t.pFile.project == p){

list.add(t);if(t.isModified()){

modified = true;}

}}

if(modified){

Object[] options = {"Si", "No", "Cancelar"};

int n = JOptionPane.showOptionDialog(null,"Algunos ficheros han sido modificados. ¿Desea guardar los cambios realizados?", "Guardar Ficheros",JOptionPane.YES_NO_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE,null,options,options[0]);

if(n == JOptionPane.YES_OPTION){

for(Tab t: list){

if (t.isModified()){

saveTabTo(t, t.pFile.file.getPath());}tabbedFilePane.remove(t);

}}else if(n == JOptionPane.NO_OPTION){

for(Tab t: list){

tabbedFilePane.remove(t);}

}else if(n == JOptionPane.CANCEL_OPTION){

result = false;}

}else{

for(Tab t: list){

tabbedFilePane.remove(t);}

}

return result;}

/** * @brief Cierra la pestaña actualmente seleccionada. */public void closeCurrentlySelectedTab(){

if(tabbedFilePane.getTabCount() > 0){

Tab t = (Tab)tabbedFilePane.getComponentAt(tabbedFilePane.getSelectedIndex());askAndRemoveTab(t);

}}

/** * @brief Cierra todas las pestañas, preguntando si guardar cambios en aquellos ficheros que se han modificado. */

163

Page 175: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

public void closeAllTabs(){

ArrayList<Tab> list = new ArrayList<Tab>();boolean modified = false;for(int i = 0, m = tabbedFilePane.getTabCount(); i < m ; i++){

Tab t = (Tab)tabbedFilePane.getComponentAt(i);list.add(t);//System.out.println(t);if(t.isModified()){

modified = true;}

}if(modified){

Object[] options = {"Si", "No", "Cancelar"};

int dialogResult = JOptionPane.showOptionDialog(null,"Algunos ficheros han sido modificados. ¿Desea guardar los cambios realizados?", "Guardar Ficheros",JOptionPane.YES_NO_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE,null,options,options[0]);

if(dialogResult == JOptionPane.YES_OPTION){

for(Tab t: list){

if (t.isModified()){

saveTabTo(t, t.pFile.file.getPath());}tabbedFilePane.remove(t);

}}else if(dialogResult == JOptionPane.NO_OPTION){

for(Tab t: list){

tabbedFilePane.remove(t);}

}else if(dialogResult == JOptionPane.CANCEL_OPTION){

//Do nothing!}

}else{

for(Tab t: list){

tabbedFilePane.remove(t);}

}

} }

164

Page 176: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.13 Project.java package xenon;

import java.io.File;import java.util.ArrayList;

import javax.swing.tree.DefaultMutableTreeNode;/** * * @brief Define un proyecto y sus propiedades básicas * */public class Project{

public File file; //Localización del proyectopublic ArrayList <ProjectFile> projectFiles; //Ficheros pertenecientes al proyectoDefaultMutableTreeNode pnode; //Nodo del proyecto en el árbol de proyectos

public Project(){

file = null;projectFiles = new ArrayList <ProjectFile>();

}public String toString(){

String s = "";if(file != null){

s = file.getName();}return s;

}

};

165

Page 177: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.14 VirtualComputer.java package xenon;

import java.util.ArrayList;import java.util.EnumMap;

/** * @brief Clase que abstrae el comportamiento del computador. * */public class VirtualComputer {

public final static int First_Semistep = 0;public final static int Last_Semistep = 1;

private Instruction[] memoryMap; //Mapa de memoria del computador

private Instruction[] InitialMemoryMap; //Mapa de memoria inicial del computadorprivate ComputerState state; //Estado del computadorprivate boolean trafficLight; //Semáforo que asegura una ejecución ordenada.private int semiStep;

/** * @brief Listener del computador * */interface VirtualComputerListener{

/** * Este método será llamado cuandoquiera que el computador quiera escribir números en pantalla. */public void writeNumberToScreen();/** * Este método será llamado cuandoquiera que el estado del computador cambie. */public void stateChanged();/** * Este método será llamado cuando el contenido de la dirección de memoria i cambie. */public void memoryChanged(Instruction i);

/** * Este método será llamado cuandoquiera que el computador quiera escribir un carácter en pantalla. */public void writeCharacterToScreen();

}

/** * @brief Enumeración de las señales del computador. */public enum ComputerSignal{

ET, ST, EE, SE, ESCP, LEET, EA, SA, EO, SUMA, RESA, MULTA, DIVA, MODA, INCP, EP, SP, ES, SD, EI, LECM, ESCM;}/** * @brief Enumeración de los registros del computador. * */public enum ComputerRegister{

A, S, T, P, I, E;}

/** * @brief Clase que define el estado del computador, a nivel de registros y señales del mismo. * */class ComputerState{

//A, I, T, E: signed 16 bit, [-32768, 32767]//P, S: unsigned 11 bit, [0, 2047]VirtualComputerListener listener;private EnumMap<ComputerSignal, Boolean> signals; //Mapa de las señalesprivate EnumMap<ComputerRegister, Boolean> changedRegisters; //Mapa de los registrosprivate boolean changedMemory;private int dirOfChanchedMemory;private int semiStep;private int A, S, T, P, I, E;

/** * @brief Constructor que inicializa los parámetros del objeto. */ComputerState(){

semiStep = First_Semistep;changedMemory = false;dirOfChanchedMemory = -1;listener = null;A = S = T = P = I = E = 0;signals = new EnumMap<ComputerSignal, Boolean>(ComputerSignal.class);changedRegisters = new EnumMap<ComputerRegister, Boolean>(ComputerRegister.class);ComputerSignal[] c = ComputerSignal.values();for(ComputerSignal i: c)

166

Page 178: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

{signals.put(i, false);

}

ComputerRegister[] r = ComputerRegister.values();for(ComputerRegister i: r){

changedRegisters.put(i, false);}

}/** * @brief Método que marca si una posición de memoria ha sido modificada en la ejecución de la última instrucción. * @param d Posición de memoria que ha cambiado. Ha de pertenecer al rango de memoria o de lo * contrario indicará que ninguna posición de memoria ha sido modificada en la ejecución * de la última instrucción. */void setChangedMemory(int d){

if (d > 0 && d < Instruction.Memory_Address_Limit){

changedMemory = true;dirOfChanchedMemory = d;

}else{

changedMemory = false;dirOfChanchedMemory = -1;

}}/** * @brief Indica si la última instrucción ejecutada ha modificado una posición de memoria. * @return */boolean hasChangedMemory(){

return changedMemory;}

void setSemiState(int s){

semiStep = s;}int getSemiState(){

return semiStep;}/** * @detail Indica qué posición de memoria ha sido modificada tras la última instrucción ejecutada. * En caso de que no se haya modificado ninguna posición, devolverá -1. * @return */int getChangedMemory(){

return dirOfChanchedMemory;}/** * @brief Llama al listener para indicarle el estado actual del computador. */public void sendSignals(){

callChange();}/** * @brief Devuelve al estado inicial (= no modificado) los registros del computador. */public void resetSignalsRegisters(){

changedMemory = false;dirOfChanchedMemory = -1;ComputerSignal[] c = ComputerSignal.values();for(ComputerSignal i: c){

signals.put(i, false);}ComputerRegister[] r = ComputerRegister.values();for(ComputerRegister i: r){

changedRegisters.put(i, false);}

}/** * @brief Marca cierto registro como modificado o no modificado. * @param s Registro * @param b true si el registro ha sido modificado, false en caso contrario */public void setRegisterChanged(ComputerRegister s, boolean b){

changedRegisters.put(s, b);}/** * @brief Indica si cierto registro ha sido modificado por la última instrucción ejecutada.

167

Page 179: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

* @param s Registro * @return */public boolean hasRegisterChanged(ComputerRegister s){

boolean b = false;try{

b = changedRegisters.get(s);}catch (NullPointerException e){}return b;

}

/** * @brief Marca cierta señal como modificada o no modificada. * @param s señal * @param b true si la señal ha sido modificada, false en caso contrario */public void setSignal(ComputerSignal s, boolean b){

signals.put(s, b);}/** * @brief Indica si cierta señal ha sido modificada por la última instrucción ejecutada. * @param s Señal * @return */public boolean getSignal(ComputerSignal s){

boolean b = false;try{

b = signals.get(s);}catch (NullPointerException e){}return b;

}/** * @brief Llama al listener para indicarle el estado actual del computador. */private void callChange(){

if(listener != null){

listener.stateChanged();}else{

//throw new NullPointerException("");}

}

/** * Asigna un listener al ComputerState * @param l Listener */void setListener(VirtualComputerListener l){

listener = l;}/** * Devuelve el listener. * @return Listener */VirtualComputerListener getListener(){

return listener;}/** * @brief Devuelve el contenido del registro A. * @return Registro A. */public int getA() {

return A;}/** * Cambia el registro A con el dato 'a' * @param a * @throws Exception Registro A fuera de rango */public void setA(int a) throws Exception {

if(a >= Instruction.Register_Min_Limit && a <= Instruction.Register_Max_Limit){

A = a;}else{

throw new Exception("Registro A fuera de rango");}

168

Page 180: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

}/** * @brief Devuelve el contenido del registro S. * @return Registro S. */public int getS() {

return S;}/** * Cambia el registro S con el dato 's' * @param s * @throws Exception Registro S fuera de rango */public void setS(int s) throws Exception {

if(s >= 0 && s <= Instruction.Memory_Address_Limit){

S = s;}else{

throw new Exception("Input register S out of boundaries");}

}/** * @brief Devuelve el contenido del registro T. * @return Registro T. */public int getT() {

return T;}/** * Cambia el registro T con el dato 't' * @param t * @throws Exception Registro T fuera de rango */public void setT(int t) throws Exception {

if(t >= Instruction.Register_Min_Limit && t <= Instruction.Register_Max_Limit){

T = t;}else{

throw new Exception("Input register T out of boundaries");}

}/** * @brief Devuelve el contenido del registro P. * @return Registro P. */public int getP() {

return P;}/** * Cambia el registro P con el dato 'p' * @param p * @throws Exception Registro P fuera de rango */public void setP(int p) throws Exception {

if(p >= 0 && p <= Instruction.Memory_Address_Limit){

P = p;

}else{

throw new Exception("Input register P out of boundaries");}

callChange();}/** * @brief Devuelve el contenido del registro I. * @return Registro I. */public int getI() {

return I;}/** * Cambia el registro I con el dato 'i' * @param i * @throws Exception Registro I fuera de rango */public void setI(int i) throws Exception {

if(i >= Instruction.Register_Min_Limit && i <= Instruction.Register_Max_Limit){

I = i;}else{

throw new Exception("Input register I out of boundaries");}

}

169

Page 181: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

/** * @brief Devuelve el contenido del registro E. * @return Registro E. */public int getE() {

return E;}/** * Cambia el registro E con el dato 'e' * @param e * @throws Exception Registro E fuera de rango */public void setE(int e) throws Exception{

if(e >= Instruction.Register_Min_Limit && e <= Instruction.Register_Max_Limit){

E = e;}else{

throw new Exception("Input register E out of boundaries");}

}/** * @brief Incrementa en una unidad el registro P. */public void incrementP(){

if(P >= Instruction.Memory_Address_Limit){

P = 0;}else{

P += 1;}

}}/** * @brief Constructor del computador, inicializa variables. */VirtualComputer(){

semiStep = First_Semistep;trafficLight = false;memoryMap = new Instruction[Instruction.Memory_Address_Limit+1];InitialMemoryMap = new Instruction[Instruction.Memory_Address_Limit+1];for(int i = 0; i < memoryMap.length; i++){

memoryMap[i] = new Instruction();InitialMemoryMap[i] = new Instruction();

}setMemoryMapToZero();state = new ComputerState();

}/** * @brief Constructor del computador que inicializa su memoria con 'memory' * @param memory Mapa de memoria del computador */VirtualComputer(ArrayList<Instruction> memory){

memoryMap = new Instruction[Instruction.Memory_Address_Limit+1];InitialMemoryMap = new Instruction[Instruction.Memory_Address_Limit+1];for(int i = 0; i < memoryMap.length; i++){

memoryMap[i] = new Instruction();InitialMemoryMap[i] = new Instruction();

}setMemoryMap(memory);state = new ComputerState();/*//Innecesario, ya lo hace setMemoryMap(memory);for(int i = 0; i < memoryMap.length; i++){

try{InitialMemoryMap[i].setInstructionSigned(memoryMap[i].getDataSigned());

}catch(Exception e){

}}*/

}/** * @brief Lleva el ordenador al estado inicial. * Pone a cero los registros y las señales, y devuelve la memoria principal a su estado inicial. */public void restart(){

try{

state.resetSignalsRegisters();

170

Page 182: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setA(0);state.setS(0);state.setT(0);state.setP(0);state.setI(0);state.setE(0);for(int i = 0; i < memoryMap.length; i++){

if(memoryMap[i].getDataSigned() != InitialMemoryMap[i].getDataSigned()){

memoryMap[i].setInstructionSigned(InitialMemoryMap[i].getDataSigned());state.getListener().memoryChanged(memoryMap[i]);

}}

}catch(Exception e){

}}/** * @brief Asigna un nuevo listener al computador * @param l Listener */public void setListener(VirtualComputerListener l){

state.setListener(l);}/** * Devuelve el listener del computador * @return Listener */VirtualComputerListener getListener(){

return state.getListener();}/** * @biref Modifica la memoria del computador con 'memory' * @param memory Mapa de memoria */public void setMemoryMap(ArrayList<Instruction> memory){

setMemoryMapToZero();for(Instruction i: memory){

memoryMap[i.getAddressLocation()]= i;}for(int i = 0; i < memoryMap.length; i++){

try{InitialMemoryMap[i].setInstructionSigned(memoryMap[i].getDataSigned());

}catch(Exception e){

}}

}/** * @brief Inicializa a cero la memoria del computador. */private void setMemoryMapToZero(){

int d = 0;for(int i = 0; i < memoryMap.length; i++){

try{memoryMap[i].setInstructionSigned(d);memoryMap[i].setAddressLocation(i);

} catch(Exception e){

//TODO:}

}}/** * @brief Devuelve el mapa de memoria del computador. * @return Mapa de memoria */public ArrayList<Instruction> getMemoryMap(){

ArrayList<Instruction> a = new ArrayList<Instruction>();for(Instruction i: memoryMap){

a.add(i);}return a;

}/** * Devuelve el estado del computador. * @return */

171

Page 183: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

ComputerState getState(){

return state;}/** * Devuelve M(D), la dirección de memoria contenida en la posición D * @param d Posición de memoria * @return * @throws IndexOutOfBoundsException */private int getIndirectAddress(int d) throws IndexOutOfBoundsException{

int r = 0;if(d < 0 || d > Instruction.Memory_Address_Limit){

throw new IndexOutOfBoundsException("" + d);}r = memoryMap[d].getDataSigned();

if(r < 0 || r > Instruction.Memory_Address_Limit){

throw new IndexOutOfBoundsException("" + r);}return r;

}/** * @brief Devuelve la próxima instrucción a ejecutar, posición que marca el registro P. * @return */public Instruction getNextInstruction(){

return memoryMap[state.getP()];}public int getSemistepInfo(){

return semiStep;}public ComputerState executeSemistep() throws Exception{

//Usamos el semáforo trafficLight para que no se puedan realizar //llamadas en paralelo/concurrentes a esta instrucción.if(trafficLight == false){

trafficLight = true;

//Recogemos la instrucción a ejecutarInstruction ins = memoryMap[state.getP()];//Marcamos todos los registros y señales como no modificadosstate.resetSignalsRegisters();state.setSemiState(semiStep);

if(semiStep == First_Semistep){

try{

//int operator = ins.getInstructionOperator();state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> I equivalente a: P -> S. M(S) -> T. T -> I.state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("Primer semipaso de instrucción");}semiStep = Last_Semistep;

}else if(semiStep == Last_Semistep){

if(ins.isInstruction() == true){

switch(ins.getOperationCode()) //Elegimos qué operación ejecutar según el código de operación.

{case ALT:

break;

172

Page 184: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

case ALM:try{

int operator = ins.getInstructionOperator();memoryMap[operator].setInstructionSigned(state.getA());state.getListener().memoryChanged(memoryMap[operator]);

state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.setT(state.getA());//state.setI(ins.getDataSigned());state.setS(operator);

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I equivalente a: P -> S. M(S) -> T. T -> I./*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//A -> M(D)state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.SA, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("ALM");}break;

case ALMI:try{

int operator = getIndirectAddress( ins.getInstructionOperator() );memoryMap[operator].setInstructionSigned(state.getA());state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.getListener().memoryChanged(memoryMap[operator]);

state.setT(state.getA());state.setI(operator);state.setS(operator);

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//A -> M(M(D))state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.SA, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

173

Page 185: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

}catch(IndexOutOfBoundsException exception){

throw new Exception("ALMI");}break;

case CAR:try{

state.setA(memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(state.getA());//state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(D) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("CAR");}break;

case CARI:try{

state.setA(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());

state.setT(state.getA());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.EA, true);

174

Page 186: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("CARI");}break;

case ESC:try{

state.setE(memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(state.getE());//state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.getListener().writeNumberToScreen();state.incrementP();//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.E, true);state.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(D) ->Estate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EE, true);state.setSignal(ComputerSignal.ESCP, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("ESC");}break;

case ESCI:try{

state.setE(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());

state.setT(state.getE());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.getListener().writeNumberToScreen();state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.E, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);

175

Page 187: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setSignal(ComputerSignal.EE, true);state.setSignal(ComputerSignal.ESCP, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("ESCI");}break;

case LEE:try{

/** * Before executing this instruction, * the input from the keyboard should have been saved into register

E. */int operator = ins.getInstructionOperator();

memoryMap[operator].setInstructionSigned(state.getE());state.setT(state.getE());//state.setI(ins.getDataSigned());state.setS(operator);

state.getListener().memoryChanged(memoryMap[operator]);state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//E -> M(D)state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LEET, true);state.setSignal(ComputerSignal.SE, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("LEE");}break;

case LEEI:try{

/** * Before executing this instruction, * the input from the keyboard should have been saved into register

E. */int operator = getIndirectAddress( ins.getInstructionOperator() );memoryMap[operator].setInstructionSigned(state.getE());

state.setT(state.getE());state.setI(operator);state.setS(operator);

state.getListener().memoryChanged(memoryMap[operator]);state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales

176

Page 188: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//A -> M(M(D))state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LEET, true);state.setSignal(ComputerSignal.SE, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("LEEI");}break;

case SUM:try{

state.setA(state.getA() + memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(memoryMap[ins.getInstructionOperator()].getDataSigned());//state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//A+M(D) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.SUMA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("SUM");}break;

case SUMI:try{

state.setA(state.getA() +

memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());

state.setT(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);

177

Page 189: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.SUMA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("SUMI");}break;

case RES:try{

state.setA(state.getA() - memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(memoryMap[ins.getInstructionOperator()].getDataSigned());//state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//A+M(D) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.RESA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("RES");}break;

case RESI:try{

state.setA(state.getA() -

memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());

state.setT(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());state.setI(getIndirectAddress( ins.getInstructionOperator() ));

178

Page 190: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.RESA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("RESI");}break;

case MUL:try{

state.setA(state.getA() * memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(memoryMap[ins.getInstructionOperator()].getDataSigned());//state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//A+M(D) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.MULTA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("MUL");}break;

case MULI:

179

Page 191: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

try{state.setA(state.getA() *

memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());

state.setT(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.MULTA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("MULI");}break;

case DIV:try{

state.setA(state.getA() / memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(memoryMap[ins.getInstructionOperator()].getDataSigned());//state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//A+M(D) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.DIVA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);

180

Page 192: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.sendSignals();}catch(IndexOutOfBoundsException exception){

throw new Exception("DIV");}break;

case DIVI:try{

state.setA(state.getA() /

memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());

state.setT(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.DIVA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("DIVI");}break;

case MOD:try{

state.setA(state.getA() % memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(memoryMap[ins.getInstructionOperator()].getDataSigned());//state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//A+M(D) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);

181

Page 193: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.MODA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("MOD");}break;

case MODI:try{

state.setA(state.getA() %

memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());

state.setT(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.MODA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("MODI");}break;

case SAL:try{

//state.setS(state.getP());//state.setT(ins.getDataSigned());//state.setI(ins.getDataSigned());

state.setP(ins.getInstructionOperator());

//Ahora señalamos qué registros han cambiado//state.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);//state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

182

Page 194: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

//D -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("SAL");}break;

case SALI:try{

state.setS(ins.getInstructionOperator());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setT(getIndirectAddress( ins.getInstructionOperator() ));

state.setP( getIndirectAddress( ins.getInstructionOperator() ) );

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(D) -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("SALI");}break;

case SAN:try{

//state.setS(state.getP());//state.setT(ins.getDataSigned());//state.setI(ins.getDataSigned());

if(state.getA() < 0){

state.setP(ins.getInstructionOperator());

//Ahora señalamos qué registros han cambiado//state.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);//state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la

ejecución de la instrucción.//Algunos setSignal los comento, pero solo para no repetir

llamadas iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//D -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

state.incrementP();

//Ahora señalamos qué registros han cambiado//state.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);//state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la

ejecución de la instrucción.//Algunos setSignal los comento, pero solo para no repetir

183

Page 195: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

llamadas iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}catch(IndexOutOfBoundsException exception){

throw new Exception("SAN");}break;

case SANI:try{

if(state.getA() < 0){

state.setS(ins.getInstructionOperator());state.setI(getIndirectAddress( ins.getInstructionOperator()

));state.setT(getIndirectAddress( ins.getInstructionOperator()

));

state.setP( getIndirectAddress( ins.getInstructionOperator() ) );

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la

ejecución de la instrucción.//Algunos setSignal los comento, pero solo para no repetir

llamadas iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(D) -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

/*state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());*/

state.incrementP();

//Ahora señalamos qué registros han cambiado/*state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);*/state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la

ejecución de la instrucción.//Algunos setSignal los comento, pero solo para no repetir

llamadas iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}catch(IndexOutOfBoundsException exception){

throw new Exception("SANI");}break;

case SAC:

184

Page 196: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

try{/*state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());*///Ahora señalamos qué registros han cambiado/*state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);*/state.setRegisterChanged(ComputerRegister.P, true);

if(state.getA() == 0){

state.setP(ins.getInstructionOperator());

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//D -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

state.incrementP();

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}catch(IndexOutOfBoundsException exception){

throw new Exception("SAC");}break;

case SACI:try{

//Ahora señalamos qué registros han cambiadoif(state.getA() == 0){

state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);

state.setS(ins.getInstructionOperator());state.setI(getIndirectAddress( ins.getInstructionOperator()

));state.setT(getIndirectAddress( ins.getInstructionOperator()

));

state.setP( getIndirectAddress( ins.getInstructionOperator() ) );

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(D) -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);

185

Page 197: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

/*state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);*/state.setRegisterChanged(ComputerRegister.P, true);

/*state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());*/

state.incrementP();

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}catch(IndexOutOfBoundsException exception){

throw new Exception("SACI");}break;

case SAP:try{

/*state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());*///Ahora señalamos qué registros han cambiado/*state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);*/state.setRegisterChanged(ComputerRegister.P, true);

if(state.getA() > 0){

state.setP(ins.getInstructionOperator());

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//D -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

state.incrementP();

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}

186

Page 198: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

catch(IndexOutOfBoundsException exception){

throw new Exception("SAP");}break;

case SAPI:try{

if(state.getA() > 0){

state.setS(ins.getInstructionOperator());state.setI(getIndirectAddress( ins.getInstructionOperator()

));state.setT(getIndirectAddress( ins.getInstructionOperator()

));

state.setP( getIndirectAddress( ins.getInstructionOperator() ) );

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(D) -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

/*state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());*/

state.incrementP();

//Ahora señalamos qué registros han cambiado/*state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);*/state.setRegisterChanged(ComputerRegister.P, true);

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}catch(IndexOutOfBoundsException exception){

throw new Exception("SAPI");}break;

case ECA:try{

state.setE(memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(state.getE());//state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

187

Page 199: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.getListener().writeCharacterToScreen();state.incrementP();//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.E, true);state.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(D) ->Estate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EE, true);state.setSignal(ComputerSignal.ESCP, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("ECA");}break;

case ECAI:try{

state.setE(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());

state.setT(state.getE());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.getListener().writeCharacterToScreen();state.incrementP();//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.E, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EE, true);state.setSignal(ComputerSignal.ESCP, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("ECAI");}break;

case LCA:try{

/** * Before executing this instruction,

188

Page 200: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

* the input from the keyboard should have been saved into register E.

*/int operator = ins.getInstructionOperator();memoryMap[operator].setInstructionSigned(state.getE());

state.setT(state.getE());//state.setI(ins.getDataSigned());state.setS(operator);

state.getListener().memoryChanged(memoryMap[operator]);state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);//state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//E -> M(D)state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LEET, true);state.setSignal(ComputerSignal.SE, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("LCA");}break;

case LCAI:try{

/** * Before executing this instruction, * the input from the keyboard should have been saved into register

E. */int operator = getIndirectAddress( ins.getInstructionOperator() );memoryMap[operator].setInstructionSigned(state.getE());

state.setT(state.getE());state.setI(operator);state.setS(operator);

state.getListener().memoryChanged(memoryMap[operator]);state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> I/*state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

//A -> M(M(D))state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);

189

Page 201: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setSignal(ComputerSignal.LEET, true);state.setSignal(ComputerSignal.SE, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("LCAI");}break;

}}else{

throw new Exception("The emulator arrived to a memory address with no instruction. The memory map may have not ben properly initialized");

}semiStep = First_Semistep;

}}//Ya hemos ejecutado la instrucción así que apagamos el semáforo.trafficLight = false;return getState();

}/** * @brief Método que ejecuta la siguiente instrucción. * @return * @throws Exception */public ComputerState executeNextInstruction() throws Exception{

//Usamos el semáforo trafficLight para que no se puedan realizar //llamadas en paralelo/concurrentes a esta instrucción.if(trafficLight == false){

trafficLight = true;//Recogemos la instrucción a ejecutarInstruction ins = memoryMap[state.getP()];//Marcamos todos los registros y señales como no modificadosstate.resetSignalsRegisters();state.setSemiState(First_Semistep);if(ins.isInstruction() == true){

switch(ins.getOperationCode()) //Elegimos qué operación ejecutar según el código de operación.{case ALT:

break;case ALM:

try{

/*int operator = ins.getInstructionOperator();

state.setT(memoryMap[operator].getDataSigned());state.setI(memoryMap[operator].getDataSigned());state.setS(state.getP());

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//M(P) -> I equivalente a: P -> S. M(S) -> T. T -> I.state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);*/

int operator = ins.getInstructionOperator();memoryMap[operator].setInstructionSigned(state.getA());state.getListener().memoryChanged(memoryMap[operator]);

state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.setT(state.getA());

190

Page 202: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setI(ins.getDataSigned());state.setS(operator);

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> I equivalente a: P -> S. M(S) -> T. T -> I.state.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//A -> M(D)state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.SA, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("ALM");}break;

case ALMI:try{

int operator = getIndirectAddress( ins.getInstructionOperator() );memoryMap[operator].setInstructionSigned(state.getA());state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.getListener().memoryChanged(memoryMap[operator]);

state.setT(state.getA());state.setI(operator);state.setS(operator);

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//A -> M(M(D))state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.SA, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("ALMI");}break;

case CAR:try{

state.setA(memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(state.getA());

191

Page 203: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(D) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("CAR");}break;

case CARI:try{

state.setA(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());

state.setT(state.getA());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("CARI");}break;

case ESC:try{

state.setE(memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(state.getE());

192

Page 204: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.getListener().writeNumberToScreen();state.incrementP();//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.E, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(D) ->Estate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EE, true);state.setSignal(ComputerSignal.ESCP, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("ESC");}break;

case ESCI:try{

state.setE(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());

state.setT(state.getE());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.getListener().writeNumberToScreen();state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.E, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EE, true);state.setSignal(ComputerSignal.ESCP, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("ESCI");}break;

case LEE:try{

/** * Before executing this instruction,

193

Page 205: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

* the input from the keyboard should have been saved into register E. */int operator = ins.getInstructionOperator();

memoryMap[operator].setInstructionSigned(state.getE());state.setT(state.getE());state.setI(ins.getDataSigned());state.setS(operator);

state.getListener().memoryChanged(memoryMap[operator]);state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//E -> M(D)state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LEET, true);state.setSignal(ComputerSignal.SE, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("LEE");}break;

case LEEI:try{

/** * Before executing this instruction, * the input from the keyboard should have been saved into register E. */int operator = getIndirectAddress( ins.getInstructionOperator() );memoryMap[operator].setInstructionSigned(state.getE());

state.setT(state.getE());state.setI(operator);state.setS(operator);

state.getListener().memoryChanged(memoryMap[operator]);state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//A -> M(M(D))state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LEET, true);state.setSignal(ComputerSignal.SE, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

194

Page 206: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("LEEI");}break;

case SUM:try{

state.setA(state.getA() + memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(memoryMap[ins.getInstructionOperator()].getDataSigned());state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//A+M(D) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.SUMA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("SUM");}break;

case SUMI:try{

state.setA(state.getA() + memoryMap[ getIndirectAddress( ins.getInstructionOperator()

) ].getDataSigned());

state.setT(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);

195

Page 207: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.SUMA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("SUMI");}break;

case RES:try{

state.setA(state.getA() - memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(memoryMap[ins.getInstructionOperator()].getDataSigned());state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//A+M(D) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.RESA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("RES");}break;

case RESI:try{

state.setA(state.getA() - memoryMap[ getIndirectAddress( ins.getInstructionOperator()

) ].getDataSigned());

state.setT(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);

196

Page 208: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.RESA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("RESI");}break;

case MUL:try{

state.setA(state.getA() * memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(memoryMap[ins.getInstructionOperator()].getDataSigned());state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//A+M(D) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.MULTA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("MUL");}break;

case MULI:try{

state.setA(state.getA() * memoryMap[ getIndirectAddress( ins.getInstructionOperator()

) ].getDataSigned());

state.setT(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);

197

Page 209: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.MULTA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("MULI");}break;

case DIV:try{

state.setA(state.getA() / memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(memoryMap[ins.getInstructionOperator()].getDataSigned());state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//A+M(D) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.DIVA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("DIV");}break;

case DIVI:try{

state.setA(state.getA() / memoryMap[ getIndirectAddress( ins.getInstructionOperator()

) ].getDataSigned());

state.setT(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

198

Page 210: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.DIVA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("DIVI");}break;

case MOD:try{

state.setA(state.getA() % memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(memoryMap[ins.getInstructionOperator()].getDataSigned());state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//A+M(D) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.MODA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("MOD");}break;

case MODI:try{

state.setA(state.getA() % memoryMap[ getIndirectAddress( ins.getInstructionOperator()

) ].getDataSigned());

state.setT(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.incrementP();

//Ahora señalamos qué registros han cambiado

199

Page 211: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setRegisterChanged(ComputerRegister.A, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EO, true);state.setSignal(ComputerSignal.MODA, true);state.setSignal(ComputerSignal.EA, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("MODI");}break;

case SAL:try{

state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());

state.setP(ins.getInstructionOperator());

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//D -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("SAL");}break;

case SALI:try{

state.setS(ins.getInstructionOperator());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setT(getIndirectAddress( ins.getInstructionOperator() ));

state.setP( getIndirectAddress( ins.getInstructionOperator() ) );

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);

200

Page 212: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setSignal(ComputerSignal.EI, true);

//M(D) -> Pstate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("SALI");}break;

case SAN:try{

state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());

if(state.getA() < 0){

state.setP(ins.getInstructionOperator());

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//D -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}catch(IndexOutOfBoundsException exception){

throw new Exception("SAN");}break;

case SANI:try{

if(state.getA() < 0){

state.setS(ins.getInstructionOperator());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setT(getIndirectAddress( ins.getInstructionOperator() ));

state.setP( getIndirectAddress( ins.getInstructionOperator() ) );

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);

201

Page 213: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(D) -> Pstate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución

de la instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas

iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}catch(IndexOutOfBoundsException exception){

throw new Exception("SANI");}break;

case SAC:

try{state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);

if(state.getA() == 0){

state.setP(ins.getInstructionOperator());

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//D -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

state.incrementP();

202

Page 214: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}catch(IndexOutOfBoundsException exception){

throw new Exception("SAC");}break;

case SACI:try{

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);if(state.getA() == 0){

state.setS(ins.getInstructionOperator());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setT(getIndirectAddress( ins.getInstructionOperator() ));

state.setP( getIndirectAddress( ins.getInstructionOperator() ) );

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(D) -> Pstate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());

state.incrementP();

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}catch(IndexOutOfBoundsException exception){

throw new Exception("SACI");}break;

case SAP:try{

state.setS(state.getP());state.setT(ins.getDataSigned());state.setI(ins.getDataSigned());

203

Page 215: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);

if(state.getA() > 0){

state.setP(ins.getInstructionOperator());

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//D -> Pstate.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

state.incrementP();

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}catch(IndexOutOfBoundsException exception){

throw new Exception("SAP");}break;

case SAPI:try{

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);if(state.getA() > 0){

state.setS(ins.getInstructionOperator());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setT(getIndirectAddress( ins.getInstructionOperator() ));

state.setP( getIndirectAddress( ins.getInstructionOperator() ) );

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(D) -> Pstate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);state.setSignal(ComputerSignal.EP, true);state.sendSignals();

}else{

state.setS(state.getP());state.setT(ins.getDataSigned());

204

Page 216: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setI(ins.getDataSigned());

state.incrementP();

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales

//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}}catch(IndexOutOfBoundsException exception){

throw new Exception("SAPI");}break;

case ECA:try{

state.setE(memoryMap[ins.getInstructionOperator()].getDataSigned());

state.setT(state.getE());state.setI(ins.getDataSigned());state.setS(ins.getInstructionOperator());

state.getListener().writeCharacterToScreen();state.incrementP();//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.E, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(D) ->Estate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EE, true);state.setSignal(ComputerSignal.ESCP, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("ECA");}break;

case ECAI:try{

state.setE(memoryMap[ getIndirectAddress( ins.getInstructionOperator() ) ].getDataSigned());

state.setT(state.getE());state.setI(getIndirectAddress( ins.getInstructionOperator() ));state.setS(getIndirectAddress( ins.getInstructionOperator() ));

state.getListener().writeCharacterToScreen();state.incrementP();//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.E, true);state.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);

//Aquí mostramos las señales usadas en el transcurso de la ejecución de la instrucción.

//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);

205

Page 217: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//M(M(D)) ->Astate.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EE, true);state.setSignal(ComputerSignal.ESCP, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("ECAI");}break;

case LCA:try{

/** * Before executing this instruction, * the input from the keyboard should have been saved into register E. */int operator = ins.getInstructionOperator();memoryMap[operator].setInstructionSigned(state.getE());

state.setT(state.getE());state.setI(ins.getDataSigned());state.setS(operator);

state.getListener().memoryChanged(memoryMap[operator]);state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//E -> M(D)state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LEET, true);state.setSignal(ComputerSignal.SE, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("LCA");}break;

case LCAI:try{

/** * Before executing this instruction, * the input from the keyboard should have been saved into register E. */int operator = getIndirectAddress( ins.getInstructionOperator() );memoryMap[operator].setInstructionSigned(state.getE());

state.setT(state.getE());state.setI(operator);state.setS(operator);

206

Page 218: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

state.getListener().memoryChanged(memoryMap[operator]);state.setChangedMemory(memoryMap[operator].getAddressLocation());

state.incrementP();

//Ahora señalamos qué registros han cambiadostate.setRegisterChanged(ComputerRegister.T, true);state.setRegisterChanged(ComputerRegister.I, true);state.setRegisterChanged(ComputerRegister.S, true);state.setRegisterChanged(ComputerRegister.P, true);//Aquí mostramos las señales usadas en el transcurso de la ejecución de la

instrucción.//Algunos setSignal los comento, pero solo para no repetir llamadas iguales//M(P) -> Istate.setSignal(ComputerSignal.SP, true);state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LECM, true);state.setSignal(ComputerSignal.ST, true);state.setSignal(ComputerSignal.EI, true);

//A -> M(M(D))state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);//state.setSignal(ComputerSignal.LECM, true);//state.setSignal(ComputerSignal.ST, true);//state.setSignal(ComputerSignal.EI, true);//state.setSignal(ComputerSignal.SD, true);//state.setSignal(ComputerSignal.ES, true);state.setSignal(ComputerSignal.LEET, true);state.setSignal(ComputerSignal.SE, true);state.setSignal(ComputerSignal.ET, true);state.setSignal(ComputerSignal.ESCM, true);

//P -> P+1state.setSignal(ComputerSignal.INCP, true);state.sendSignals();

}catch(IndexOutOfBoundsException exception){

throw new Exception("LCAI");}break;

}}else{

throw new Exception("The emulator arrived to a memory address with no instruction. The memory map may have not ben properly initialized");

}}//Ya hemos ejecutado la instrucción así que apagamos el semáforo.trafficLight = false;return getState();

}}

207

Page 219: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.15 Instruction.java package xenon;

/** * * @brief Clase que contiene una instrucción * */public class Instruction {

//Constantes útilespublic static final int Memory_Address_Limit = 2047;public static final int Instruction_Size_Limit = 65535;public static final int Register_Max_Limit = 32767;public static final int Register_Min_Limit = -32768;public static final int Operation_Code_Max = 31;/** * * @brief Códigos de operación. * */public enum OperationCode {

ALT(0, 0), ALM(1, 2), ALMI(2, 3), CAR(3, 4), CARI(4, 5), ESC(5, 6), ESCI(6, 7), LEE(7, 8), LEEI(8, 9), SUM(9, 10), SUMI(10, 11), RES(11, 12),RESI(12, 13), MUL(13, 14), MULI(14, 15), DIV(15, 16), DIVI(16, 17), MOD(17, 18), MODI(18, 19), SAL(19, 20), SALI(20, 21), SAN(21, 22), SANI(22, 23), SAC(23, 24),SACI(24, 25), SAP(25, 26), SAPI(26, 27), ECA(27, 28), ECAI(28, 29), LCA(29, 30), LCAI(30, 31);

private int index;//Código de operación, en base 10private int code;OperationCode(int i, int c){

index = i;code = c;

}public int index(){

return index;}public int code(){

return code;}public boolean addressingMode(){

return ((code & 0x01) == 1)? true : false;}

};//Una instrucción es un código de operación + operador (una dirección de memoria)private OperationCode operationCode;private int insOperator; //Operador de la instrucción (normalmente será una dirección de memoria)private int data; //sin signo 16 bit, [0, 65535]. Los números negativos se guardarán en complemento a 2 de 16bitprivate boolean isInstruction;private int addressLocation;/** * @brief Constructor. */Instruction(){

data = 0;isInstruction = false;insOperator = -1;addressLocation = -1;

}/** * @detail Constructor que inicializa el contenido de la instrucción (código+operador), * pero no define la posición de memoria en que se encuentra la instrucción. * @param oc Código de operación * @param operator operador */Instruction(OperationCode oc, int operator){

addressLocation = -1;data = 0;isInstruction = false;insOperator = -1;setInstruction(oc, operator);

}

/** * @detail Método que inicializa el contenido de la instrucción (código+operador), * pero no define la posición de memoria en que se encuentra la instrucción. * @param oc Código de operación * @param operator operador */public int setInstruction(OperationCode oc, int operator)//TODO: throws Exception{

208

Page 220: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

int r = 0;operationCode = oc;if(operator <= Memory_Address_Limit && operator >= 0){

if(oc != null){

isInstruction = true;insOperator = operator;

}else {

isInstruction = false;r = -2;

}}else{

isInstruction = false;r = -1;

}updateFromInstruction();return r;

}/** * @detail Sitúa la instrucción en la posición de memoria 'ma'. * @param ma posición de memoria de la instrucción * @return * @throws Exception Será lanzada si la posición de memoria está fuera de rango */public int setAddressLocation(int ma) throws Exception{

int r = -1;if(ma <= Memory_Address_Limit && ma >= 0){

addressLocation = ma;r = 0;

}else{

throw new Exception("Error: Dirección " + ma + " fuera de rango");}return r;

}/** * @brief Devuelve la posición de memoria de la instrucción * @return Posición de memoria de la instrucción */public int getAddressLocation(){

return addressLocation;}

public boolean isInstruction(){

return isInstruction;}/** * Método que cambia el código de operación de la instrucción * @param oc * @return * TODO: Eliminar return parametro */public int setOperationCode(OperationCode oc){

operationCode = oc;int r = 0;if(insOperator <= Memory_Address_Limit && insOperator >= 0){

if(operationCode != null){

isInstruction = true;

}else {

isInstruction = false;r = -2;

}}else{

isInstruction = false;r = -1;

}updateFromInstruction();return r;

}/** * Método que cambia el operador de la instrucción * @param operator * @return

209

Page 221: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

*/public int setInstructionOperator(int operator){

int r = 0;if(operator <= Memory_Address_Limit && operator >= 0){

if(operationCode != null){

isInstruction = true;

}else {

isInstruction = false;r = -2;

}insOperator = operator;updateFromInstruction();

}else{

isInstruction = false;r = -1;

}return r;

}

/** * @brief Toma como entrada el dato (con signo) que corresponde a la instrucción. * El parámetro d debe pertenecer a [-32768, 32767] o lanzará una excepción */public void setInstructionSigned(int d) throws Exception{

if(d >= -(Instruction_Size_Limit+1)/2 && d <= (Instruction_Size_Limit+1)/2 -1){

if(d >= 0) {

data = d; }

else {

//Pasamos de número negativo a complemento a 2 (16bit).data = d+(Instruction_Size_Limit+1);

}updateFromData();

}else{

throw new Exception("The number " + d + " cannot be an instruction");}

}

/** * @brief Toma como entrada el dato (sin signo) que corresponde a la instrucción. * El parámetro d debe pertenecer a [0, 65535] o lanzará una excepción. */public void setInstructionUnsigned(int d) throws Exception{

if(d >= 0 && d <= Instruction_Size_Limit){ data = d;

updateFromData();}else{

throw new Exception("The number " + d + " cannot be an instruction");}

}/** * Devuelve el código de operación de la instrucción. * @return Código de operación */public OperationCode getOperationCode(){

return operationCode;}/** * Devuelve el operador de la instrucción * @return Operador de la instrucción */public int getInstructionOperator(){

return insOperator;}/** * Devuelve el dato guardado en memoria, sin signo * @return */

210

Page 222: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

public int getDataUnsigned(){

return data;}/** * Devuelve el dato guardado en memoria, con signo * @return */public int getDataSigned(){

int r = 0;int conditional = (((Instruction_Size_Limit+1)/2)-1);if(data <= conditional){

r = data;}else{

//Pasamos de complemento a 2 a número con signor = data-(Instruction_Size_Limit+1);

}return r;

}/** * @brief Calcula qué código de operación y operador tiene la instrucción a partir del dato guardado en memoria */private void updateFromData(){

//int oc = (data & 0xF000) >> 12;int code = (data & 0xF800) >> 11;//if( oc >= 0 && oc <= Operation_Code_Max )if( code >= 0 && code <= Operation_Code_Max ){

int i = -1;for(OperationCode getIndex: OperationCode.values()){

if(code == getIndex.code()){

i = getIndex.index();break;

}}if(i != -1){

operationCode = OperationCode.values()[i];insOperator = (data & 0x07FF);isInstruction = true;

}else{

isInstruction = false;}

}else{

isInstruction = false;}

}/** * Calcula el dato a guardar en memoria */private void updateFromInstruction(){

int foo = 0;if(isInstruction()){

foo = (operationCode.code() << 11) | insOperator;}else{

if(operationCode == null && insOperator != -1){

foo = insOperator;}else if (operationCode != null&& insOperator == -1){

foo = operationCode.code() << 11;}

}

try{setInstructionUnsigned(foo);

}catch(Exception e){

//TODO: }

}

/**

211

Page 223: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

* @brief Crea una cadena que representa la instrucción. */public String toString(){

String s = null;if(isInstruction()){

if(operationCode == OperationCode.ALT){

s = Integer.toString(addressLocation,16)+ ": " + operationCode.name()+ " : " + Integer.toString(getDataSigned(), 16);

}else{

s = Integer.toString(addressLocation,16)+ ": " + operationCode.name()+ " " + Integer.toString(insOperator, 16) + " : " +

Integer.toString(getDataSigned(), 16);}

}else{

s = Integer.toString(addressLocation,16)+ ": " + Integer.toString(getDataSigned(), 16);}return s;

}}

212

Page 224: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.16 ProjectsManager.java package xenon;

import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.io.File;import java.io.FilenameFilter;import java.util.ArrayList;

import javax.swing.JFileChooser;import javax.swing.JOptionPane;import javax.swing.JTree;import javax.swing.tree.DefaultMutableTreeNode;import javax.swing.tree.DefaultTreeModel;import javax.swing.tree.TreePath;import javax.swing.tree.TreeSelectionModel;

/** * * @brief Clase gestora de los proyectos abiertos * */public class ProjectsManager implements MouseListener {

ArrayList<Project> projectsList; //Lista de proyectosProject currentlySelectedProject;//Proyecto que se encuentra seleccionado actualmenteProjectFile currentlySelectedFileInJTree; //Fichero seleccionado en el árbol de ficherosJTree projectsTree; //Árbol de ficherosTabsManager tabsManager; //Gestor de pestañas

public ProjectsManager(TabsManager tm){

//Inicializamos variablescurrentlySelectedFileInJTree = null;projectsList = new ArrayList<Project>();DefaultMutableTreeNode top = new DefaultMutableTreeNode("Proyectos");projectsTree = new JTree(top);projectsTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);projectsTree.addMouseListener(this);tabsManager = tm;currentlySelectedProject = null;

}

public JTree getProjectsTree(){

return projectsTree;}public Project getCurrentlySelectedProject(){

return currentlySelectedProject;}public ProjectFile getCurrentlySelectedFileInJTree(){

return currentlySelectedFileInJTree;}

public void closeProject(){

boolean b = true;if(currentlySelectedProject != null){

//Cerramos pestañasb = tabsManager.closeAllTabsOfProject(currentlySelectedProject);

//Si todo fue bien eliminamos los nodos del proyecto del árbol de proyectosif (b == true){

DefaultTreeModel model = (DefaultTreeModel) projectsTree.getModel();model.removeNodeFromParent(currentlySelectedProject.pnode);projectsTree.setModel(model);projectsList.remove(currentlySelectedProject);

}}

}

/** * @brief Elimina un fichero del árbol de proyectos * @param pf */public void removeFileFromJTree(ProjectFile pf){

TreePath tp = new TreePath(pf.project.pnode.getPath());DefaultMutableTreeNode root = (DefaultMutableTreeNode)projectsTree.getModel().getRoot();DefaultTreeModel tm = new DefaultTreeModel(root);pf.project.projectFiles.remove(pf);pf.project.pnode.remove(pf.fnode);

213

Page 225: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

projectsTree.setModel(tm);projectsTree.expandPath(tp);

}

/** * * @param pf * @return */public File addBinaryFromCode(ProjectFile pf){

String arg1 = pf.file.getPath();int lastIndex = arg1.lastIndexOf('.');String str = arg1.substring(0, lastIndex) + ".ece";File filep = new File(str);

//Si el fichero ya existe en el árbol, no necesitamos añadirlo boolean flag = true; for(ProjectFile p : pf.project.projectFiles) { if( filep.getAbsolutePath().equals( p.file.getAbsolutePath() ) ) { flag = false; filep = p.file; } } //Si flag == true, el fichero todavía no existe en el árbol de proyectos, luego lo añadimos

if(flag == true){

DefaultMutableTreeNode root = (DefaultMutableTreeNode)projectsTree.getModel().getRoot();

//Creamos un nuevo ProjectFileProjectFile prfile = new ProjectFile(filep, pf.project);//Añadimos dicho ProjectFile a la lista de ficheros del proyectopf.project.projectFiles.add(prfile);//Creamos un TreeNode para dicho ProjectFileDefaultMutableTreeNode node = new DefaultMutableTreeNode(prfile);prfile.setNode(node);//Añadimos dicho nodo a la lista de nodos del proyectopf.project.pnode.add(node);

//Actualizamos el modelo del árbol de proyectos DefaultTreeModel tm = new DefaultTreeModel(root); projectsTree.setModel(tm); //Seleccionamos el nodo perteneciente al fichero añadido en el árbol de proyectos projectsTree.expandPath(new TreePath(pf.project.pnode.getPath())); //System.out.println("Añadido fichero " + filep.getName() + " al proyecto " + pf.project.file.getName() // + " " + pf.project.pnode.isNodeChild(node));

}

return filep;}/** * @brief Crea un nuevo proyecto. */public void createProject(){

JFileChooser fc = new JFileChooser();fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);int returnVal = fc.showDialog(null, "Nuevo Proyecto");if (returnVal == JFileChooser.APPROVE_OPTION) {

File projectDir = fc.getSelectedFile(); if(projectDir.exists()) {

JOptionPane.showMessageDialog(null, "El proyecto no ha podido ser creado en el directorio elegido " + "porque dicho directorio ya existe."); } else { //Creamos un nuevo directorio boolean success = projectDir.mkdir(); if(success) { //Creamos un fichero ls2 con el nombre del proyecto File f = new File(projectDir.getAbsolutePath() + "/" + projectDir.getName() + ".ls2"); try{ f.createNewFile(); } catch(Exception y) { } //Abrimos el proyecto openProject(projectDir); }

214

Page 226: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

else { JOptionPane.showMessageDialog(null,

"Ha ocurrido un error al crear el directorio del proyecto."); } } System.out.println("Creando proyecto en: " + projectDir.getPath() + "."); } else { System.out.println("Comando de crear proyecto cancelado por el usuario."); }

}/** * @brief Abre el proyecto que está en el directorio que contiene el parámetro file * @param file */private void openProject(File file){

//Comprobamos si dicho proyecto ya está abierto boolean flag = true; for(Project p : projectsList) { if( file.getPath().equals( p.file.getPath() ) ) { flag = false; } } //Si flag == true, el proyecto todavía no se ha abierto if (flag == true) { System.out.println("Abriendo: " + file.getAbsolutePath() + "."); //Creamos un filtro de forma que solo obtengamos ficheros con las extensiones txt, ls2 o ece FilenameFilter filter = new FilenameFilter(){

@Overridepublic boolean accept(File arg0, String name) { String arg1 = name.toLowerCase(); if(arg1.lastIndexOf('.')>0)

{ // get last index for '.' char int lastIndex = arg1.lastIndexOf('.'); // get extension String str = arg1.substring(lastIndex); // match path name extension if(str.equals(".txt") || str.equals(".ls2") || str.equals(".ece")) { return true; } }

return false;}

}; //Obtenemos la lista de ficheros del proyecto aplicando el filtro. File[] fileList = file.listFiles(filter); Project p = new Project(); p.file = file;

DefaultMutableTreeNode root = (DefaultMutableTreeNode)projectsTree.getModel().getRoot(); //Nodo del proyecto en el árbol de proyectos DefaultMutableTreeNode project = new DefaultMutableTreeNode(p); p.pnode = project; DefaultMutableTreeNode node; for(File filep:fileList) { if(filep.exists()) { //Añadimos el fichero al proyecto ProjectFile prfile = new ProjectFile(filep, p); p.projectFiles.add(prfile); node = new DefaultMutableTreeNode(prfile); prfile.setNode(node); project.add(node); //tabsManager.addTab(prfile); } } //Añadir proyecto a la lista de proyectos root.add(project); //Actualizar el modelo del árbol de proyectos con los nuevos nodos DefaultTreeModel tm = new DefaultTreeModel(root); projectsTree.setModel(tm); //Seleccionar el proyecto que acabamos de abrir

215

Page 227: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

projectsTree.expandPath(new TreePath(project.getPath())); projectsList.add(p); }

}

/** * @brief Muestra una ventana para seleccionar el proyecto que queremos abrir, y luego abre dicho proyecto */public void openProject(){

JFileChooser fc = new JFileChooser();fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);int returnVal = fc.showDialog(null, "Abrir Proyecto");if (returnVal == JFileChooser.APPROVE_OPTION) {

File file = fc.getSelectedFile();openProject(file);

} else { System.out.println("Comando de apertura cancelado por el usuario."); }

}

@Overridepublic void mouseClicked(MouseEvent arg0) {

}

@Overridepublic void mouseEntered(MouseEvent arg0) {

}

@Overridepublic void mouseExited(MouseEvent arg0) {

}/** * @detail Un click selecciona el fichero/proyecto. Dos clicks abre el fichero en cuestión */@Overridepublic void mousePressed(MouseEvent e) {

int selRow = projectsTree.getRowForLocation(e.getX(), e.getY()); TreePath selPath = projectsTree.getPathForLocation(e.getX(), e.getY()); if(selRow != -1) { if(e.getClickCount() == 2) //doble click, abrir fichero seleccionado

{ DefaultMutableTreeNode node = (DefaultMutableTreeNode)selPath.getLastPathComponent(); if(selPath.getPathCount() == 3 && node.isLeaf()) { ProjectFile pf = (ProjectFile)node.getUserObject(); //System.out.println(selPath.getPathCount() + " " + selPath + " " + pf.file.getPath()); //Añadir pestaña, o, si ya existía, seleccionarla y mostrar el archivo tabsManager.addTab(pf); }

} else if(e.getClickCount() == 1) //un click, actualizamos el fichero y proyecto seleccionados { DefaultMutableTreeNode l = (DefaultMutableTreeNode)selPath.getLastPathComponent();

if(selPath.getPathCount() >= 2) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)selPath.getPathComponent(1); currentlySelectedProject = (Project)node.getUserObject(); //System.out.println(currentlySelectedProject); } if(selPath.getPathCount() == 3 && l.isLeaf()) { currentlySelectedFileInJTree = (ProjectFile)l.getUserObject(); } else { currentlySelectedFileInJTree = null; }

} }

}

@Overridepublic void mouseReleased(MouseEvent arg0) {

}}

216

Page 228: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.17 XenonHelper.javapackage xenon;

import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.ArrayList;

/** * * @brief Clase que realiza tareas de compilación y lectura de binarios. * */public class XenonHelper {

/** * * @brief Lista de pseudoinstrucciones * */public enum PseudoInstruction { ORG, ESP, CTE, FIN, DRE };

/* * Este método recoge la salida del método translateToInstructions(String) y lo convierte * en un mapa de memoria */public static ArrayList<Instruction> generateMemoryMap(ArrayList<Instruction> in){

int n = 0;

//Primero localizamos la dirección de memoria más alta con alguna instrucción.for(Instruction i: in){

int m = i.getAddressLocation();if(m > n){

n = m;}

}

ArrayList<Instruction> map = new ArrayList<Instruction>(n+1);

int d = 0;

//Rellenamos el mapa de memoria con instrucciones en blancofor(int i = 0; i <= n; i++){

Instruction e = new Instruction();try{

e.setAddressLocation(i);e.setInstructionSigned(d);

}catch(Exception x){

//TODO}map.add(e);

}//Reemplazamos las instrucciones en blanco con las realesfor(Instruction i: in){

map.set(i.getAddressLocation(), i);}return map;

}

/** * @brief Lee una cadena de texto y la traduce a instrucciones * @param code * @return */@SuppressWarnings("unused")public static ArrayList<Instruction> translateToInstructions(String code) throws Exception{

ArrayList<Instruction> array = new ArrayList<Instruction>();

ArrayList<LineCode> lineCodeArray = new ArrayList<LineCode>();String[] lines = code.split(System.getProperty("line.separator"));int lineCounter = 0;boolean arrivedToFIN = false;for(String line: lines){

if(arrivedToFIN == false){

lineCounter++;boolean thereIsSomething = false;LineCode l = new LineCode();//String[] words = line.split(" ");String[] words = line.split("\\s+");

217

Page 229: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

ArrayList<String> awords = new ArrayList<String>();

String mensaje = new String("");for(String w: words){

if(w.indexOf(" ") == -1 && w.length() > 0){

awords.add(new String(w));}

}words = awords.toArray(new String[awords.size()]);

for(String w: words){

mensaje += " | " + w ;}//System.out.println("Línea " + lineCounter + " : " + mensaje);int index = 0;if(words.length > 0){

if(words[index].lastIndexOf(":") == words[index].length()-1 && words[index].length() > 1)

{l.label = words[index].substring(0, words[0].length()-1);index++;

}}if(words.length > index){

try{

l.instruction.setOperationCode(Instruction.OperationCode.valueOf(words[index]));index++;if(words.length == index + 1){

//There is an addressthereIsSomething = true;l.addressLabel = words[index];

}else if(l.instruction.getOperationCode() == Instruction.OperationCode.ALT){

thereIsSomething = true;l.addressLabel = "0";

}else if(words.length == index ){

throw new Exception("Error en línea " + lineCounter +" : falta dirección de memoria en la instrucción:

" + line);}else if(words.length >= index + 2){

throw new Exception("Error en línea " + lineCounter +" : la instrucción solo ha de tener un argumento:

" + line);}

}catch (IllegalArgumentException e){

try{l.pseudoInstruction = PseudoInstruction.valueOf(words[index]);

}catch(Exception excp){

throw new Exception("Error en línea " + lineCounter +" : instrucción '" + words[index] + "' no

reconocida en: "+ line );}

index++;if(l.pseudoInstruction == PseudoInstruction.FIN){

if(words.length == index){

thereIsSomething = true;arrivedToFIN = true;

}else{

throw new Exception("Error en línea " + lineCounter +

" : La pseudoinstrucción FIN no ha de tener argumentos: " + line);

}

//Salimos del bucle forbreak;

}else if(l.pseudoInstruction == PseudoInstruction.ORG){

if(words.length == index +1){

218

Page 230: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

l.addressLabel = words[index];thereIsSomething = true;

}else if (words.length == index){

throw new Exception("Error en línea " + lineCounter +

" : falta dirección de memoria en la pseudoinstrucción: " + line);

}else if (words.length >= index +2){

throw new Exception("Error en línea " + lineCounter +

" : la pseudoinstrucción solo ha de tener un argumento: " + line);

}}else if(l.pseudoInstruction == PseudoInstruction.ESP){

if(words.length == index +1){

l.addressLabel = words[index];thereIsSomething = true;

}else if (words.length >= index +2){

throw new Exception("Error en línea " + lineCounter +

" : la pseudoinstrucción solo ha de tener un argumento: " + line);

}else if (words.length == index){

throw new Exception("Error en línea " + lineCounter +

" : falta número de espacios en la pseudoinstrucción: " + line);

}}else if(l.pseudoInstruction == PseudoInstruction.CTE){

if(words.length == index + 1){

//l.addressLabel = words[index];int bar = -1;try{

bar = Integer.parseInt(words[index]);}catch (Exception ex){

throw new Exception("Error en línea " + lineCounter +

" : la constante "+ words[index] + " no es un número: " + line.toString());

}if(bar < Instruction.Register_Min_Limit || bar >

Instruction.Register_Max_Limit){

throw new Exception("Error en línea " + lineCounter +

" : constante fuera de rango en la pseudoinstrucción: " + line.toString());

}else {

l.instruction.setInstructionSigned(bar);thereIsSomething = true;

}}else if (words.length == index){

throw new Exception("Error en línea " + lineCounter +

" : falta definir la constante en la pseudoinstrucción: " + line.toString());

}else if (words.length >= index +2){

throw new Exception("Error en línea " + lineCounter +

" : la pseudoinstrucción solo ha de tener un argumento: " + line);

}}else if(l.pseudoInstruction == PseudoInstruction.DRE){

if(words.length == index +1){

l.addressLabel = words[index];thereIsSomething = true;

}

219

Page 231: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

else if (words.length == index){

throw new Exception("Error en línea " + lineCounter +

" : falta etiqueta en la instrucción: " + line);

}else if (words.length >= index +2){

throw new Exception("Error en línea " + lineCounter +

" : la pseudoinstrucción solo ha de tener un argumento: " + line);

}}

}}if(thereIsSomething){

l.lineNumber = lineCounter;l.address = lineCodeArray.size();lineCodeArray.add(l);

} }

}if(arrivedToFIN == false){

throw new Exception("Error de sintaxis: Falta la directiva FIN" );}

//Hemos leído las lineas, pero no hemos interpretado dónde está cada línea dentro de la posición de memoriaint indexCounter = 0;int lastORGContent = 0;int lastORGIndex = 0;

int lastESPContent = 0;/** * TODO: La instrucción ESP 4 debría dejar 4 espacios (cada espacio es del tamaño de una instr, 2 bytes) * en blanco. */for(LineCode line: lineCodeArray){

if(line.pseudoInstruction == PseudoInstruction.ORG){

//El +1 es porque ORG es una pseudoinstrucción que no se encuentra en ninguna posición de memorialastORGIndex = indexCounter + 1;try {

lastORGContent = Integer.parseInt(line.addressLabel);line.instruction.setAddressLocation(lastORGContent);line.address = line.instruction.getAddressLocation();lastESPContent = 0;

}catch (Exception e){

throw new Exception("Error en línea " + line.lineNumber +" : '" + line.addressLabel + "' no es un número: " +

lines[line.lineNumber-1]);}

}else if(line.pseudoInstruction == PseudoInstruction.ESP){

int a =0;

line.address = lastORGContent + lastESPContent + indexCounter - lastORGIndex;try {

a = Integer.parseInt(line.addressLabel)-1;

}catch (Exception e){

throw new Exception("Error en línea " + line.lineNumber +" : '" + a + "' no es un número: " + lines[line.lineNumber-1]);

}

if(a < 0){

throw new Exception("Error en línea " + line.lineNumber +" : El argumento '" + (a+1) + "' es un número de espacios menor que

1: " + lines[line.lineNumber-1]);

}else if(lastESPContent + line.address + a > Instruction.Memory_Address_Limit){

throw new Exception("Error en línea " + line.lineNumber +" : Añadir '" + (int)(a+1) +"' espacios no es posible porque no hay memoria suficiente: "+ lines[line.lineNumber-1]);

}

220

Page 232: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

else{

lastESPContent += a;line.instruction.setAddressLocation(line.address);

}

}else{

line.address = lastORGContent + lastESPContent + indexCounter - lastORGIndex;line.instruction.setAddressLocation(line.address);

}indexCounter++;

}//Ahora sustituimos las etiquetas por direcciones de memorialineCounter = 0;for(LineCode line: lineCodeArray){

if(line.label != null){

try {int a = Integer.parseInt(line.label);

throw new Exception("Error en línea " + line.lineNumber +" : La etiqueta '" + a + "' no puede ser un número: " +

lines[line.lineNumber-1]);}catch (NumberFormatException e){

searchLabel(lineCodeArray, line.label);}

}if(line.addressLabel != null && line.pseudoInstruction == null){

int address = searchLabel(lineCodeArray, line.addressLabel);if(address > 0 ){

line.instruction.setInstructionOperator(address);}else if (address == -1){

//Comprobar si la etiqueta es un númerotry {

address = Integer.parseInt(line.addressLabel);

}catch(Exception e) {

throw new Exception("Error en línea " + line.lineNumber +" : Etiqueta '" + line.addressLabel + "' no encontrada: " +

lines[line.lineNumber - 1]);}int r = line.instruction.setInstructionOperator(address);if( r == -1){

throw new Exception("Error en línea " + line.lineNumber +" : Dirección de memoria '" + line.addressLabel + "' fuera

de rango: " + lines[line.lineNumber - 1]);

}else{

//Todo ok}

}}else if(line.addressLabel != null && line.pseudoInstruction == PseudoInstruction.DRE){

int address = searchLabel(lineCodeArray, line.addressLabel);if(address > 0 ){

line.instruction.setInstructionOperator(address);}else if (address == -1){

//Comprobar si la etiqueta es un númerotry {

address = Integer.parseInt(line.addressLabel);}catch(Exception e) {

throw new Exception("Error en línea " + line.lineNumber +" : Etiqueta '" + line.addressLabel + "' no encontrada: "+ lines[line.lineNumber - 1]);

}throw new Exception("Error en línea " + line.lineNumber +

" : El operador '" + line.addressLabel + "' de la pseudoinstrucción ha de ser una etiqueta: " + lines[line.lineNumber - 1]);

}

221

Page 233: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

}

lineCounter++;}int okay = 0;for(LineCode line: lineCodeArray){

okay = line.check();switch(okay){case 0:

break;case -1:

throw new Exception("Error: número de línea negativo " + line.lineNumber);case -2:

throw new Exception("Error en la línea " + line.lineNumber +" : memoria fuera de rango" );

case -3:throw new Exception("Error en la línea " + line.lineNumber +

" : pseudoInstruction e instruction nulos! ");case -4:

throw new Exception("Error: número de línea negativo " + line.lineNumber +" : Pseudoinstrucción FIN no procesada correctamente");

default:throw new Exception("Error no reconocido");

}}

//Rellenamos el array de instruccionesfor(LineCode line: lineCodeArray){

if(line.pseudoInstruction != null){

switch(line.pseudoInstruction){

case ORG:

//Todo OKbreak;

case FIN://No deberíamos haber guardado esta pseudo instrucción!!throw new Exception("Error: número de línea negativo" + line.lineNumber +

" : Pseudoinstrucción FIN no procesada correctamente");case ESP:

array.add(line.instruction);break;

case CTE:array.add(line.instruction);break;

case DRE:array.add(line.instruction);break;

}}else if(line.instruction != null && line.instruction.isInstruction()){

array.add(line.instruction);}

}

return array;

}/** * @brief Busca una etiqueta en una lista de líneas de código. */private static int searchLabel(ArrayList<LineCode> lineCodeArray, String addressLabel) throws Exception{

int indexCounter = 0;int out = -1; //Etiqueta no encontradaint lastMod = 0;for(LineCode line: lineCodeArray){

if(addressLabel.equals(line.label)){

if(out != -1){

throw new Exception("Error en línea " + lineCodeArray.get(lastMod).lineNumber +" : etiqueta '" + line.label + "' duplicada en la línea: "+ line.lineNumber);

}else{

lastMod = indexCounter;out = line.address;

}}indexCounter++;

}return out;

222

Page 234: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

}

/** * @brief Traduce a binario un programa, una vez tenemos las instrucciones que lo forman. * Este es el principal método que permite guardar en formato “ece” el código binario de un programa. */public static byte[] translateToBinary(ArrayList<Instruction> code){

byte[] binary = new byte[(Instruction.Memory_Address_Limit+1)*2];int foo = 0;for(Instruction i: code){

foo = i.getDataUnsigned();//BigEndian or LittleEndian?binary[i.getAddressLocation()*2] = intToByte(foo & 0x00FF);binary[i.getAddressLocation()*2 + 1] = intToByte((foo & 0xFF00) >> 8);

}

return binary;}/** * @brief Método usado para convertir de int a byte. */public static byte intToByte(int i){

return (byte)i;}

/** * @brief Método usado para convertir de byte a int. */public static int byteToInt(byte b){

int i = (byte)b;if(b < 0){

i = i - 2*((int)Byte.MIN_VALUE);}return i;

}

/** * @brief Traduce código binario a un mapa de memoria que contiene un programa. * Es el método principal a la hora de leer código binario y traducirlo a instrucciones * que entienda el computador virtual Xenon. */public static ArrayList<Instruction> translateFromBinary(byte[] binary){

ArrayList<Instruction> array = new ArrayList<Instruction>();

int foo = 0;Instruction sr;for(int i = 0; i < binary.length/2; i++){

//BigEndian or LittleEndian?foo= byteToInt(binary[i*2]) + (byteToInt(binary[i*2 + 1]) << 8); if(foo != 0){

sr = new Instruction();try{

sr.setInstructionUnsigned(foo);sr.setAddressLocation(i);

}catch(Exception e){

}array.add(sr);

}}return array;

}

/** * @brief Abre un fichero binario y devuelve el mapa de instrucciones. * @param file * @return * @throws Exception * @throws FileNotFoundException */public static ArrayList<Instruction> openBinaryFile(File file) throws Exception, FileNotFoundException{

long lSize=file.length();int size= (int)lSize;if(lSize > Integer.MAX_VALUE){

throw new Exception("File is too big");}

223

Page 235: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

byte[] contents=new byte[size];

try{

FileInputStream fis = new FileInputStream(file);

fis.read(contents, 0, size);fis.close();

}catch (FileNotFoundException e){

throw e;}

return translateFromBinary(contents);}

/** * @brief Guarda el código binario de un programa en formato "ece". * @param file * @param ins * @throws IOException * @throws FileNotFoundException */public static void saveToBinaryFile(File file, ArrayList<Instruction> ins) throws IOException, FileNotFoundException{

byte[] contents = translateToBinary(ins);try{

FileOutputStream fos = new FileOutputStream(file);fos.write(contents, 0, contents.length);fos.flush();fos.close();

}catch (FileNotFoundException e){

throw e;}catch (IOException e){

throw e;}

}

}

224

Page 236: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

11.1.18 Interface.javapackage xenon;

import java.awt.Container;import java.awt.EventQueue;import java.awt.Rectangle;

import javax.swing.AbstractAction;import javax.swing.Action;import javax.swing.ImageIcon;import javax.swing.JCheckBox;import javax.swing.JDialog;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JPopupMenu;import javax.swing.JScrollPane;import javax.swing.JSlider;import javax.swing.JSplitPane;import javax.swing.JTabbedPane;import javax.swing.JTextArea;import javax.swing.JToolBar;import javax.swing.JTree;import javax.swing.KeyStroke;import javax.swing.JButton;import java.awt.event.ActionEvent;import java.awt.event.KeyEvent;import java.awt.event.MouseListener;import java.awt.event.MouseWheelEvent;import java.awt.event.MouseWheelListener;

import javax.swing.GroupLayout;import javax.swing.GroupLayout.Alignment;import javax.swing.event.ChangeEvent;import javax.swing.event.ChangeListener;

import java.awt.CardLayout;import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.util.ArrayList;

// Font source: http://art.gnome.org/themes/icon?page=2// License: GPL

/** * @brief Vista principal del entorno de desarrollo * @details * En esta clase se encuentra el main(). Permite conmutar entre las vistas de desarrollo y depuración, * así como entrar en la vista de emulación. * */public class Interface extends JFrame {

/** * * @brief Listener que actualiza la frecuencia de ejecución cuando cambia el slider. * */class SliderListener implements ChangeListener {

//Etiqueta que muestra al usuario la frecuencia escogida.private JLabel label;DebugViewManager manager;SliderListener(JLabel l, DebugViewManager dvm){

label = l;manager = dvm;

}@Overridepublic void stateChanged(ChangeEvent arg0) {

JSlider source = (JSlider)arg0.getSource();long hz = (long)source.getValue();

label.setText(hz + " Hz"); if (!source.getValueIsAdjusting() && manager != null) { //Usamos 1000/f porque la función setExecutionPeriod hace uso de T=milisegundos. manager.setExecutionPeriod(1000L/hz); }

}}

/** * */private static final long serialVersionUID = 1L;JPanel cardPanel; //Panel que usa CardLayout para cambiar entre la vista de depuración y de código.

225

Page 237: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

final static String CODEVIEW = "Code"; final static String DEBUGVIEW = "Debug"; String state = CODEVIEW; //Variable que informa de si estamos actualmente en la vista de código o de depuración

JTree projectsTree; //Árbol de proyectosTabsManager tabsManager; //Gestor de pestañas.DebugViewManager debugViewManager; //Controlador principal de la vista de depuraciónJTextArea problemasArea; //Área que informa de problemas en la vista de desarrolloJLabel time;//CesiusHelper core;ProjectsManager projectsManager;JSlider slider; //Slider que sirve para cambiar la frecuencia de ejecución del computador.

/** * @brief Añade todos los componentes necesarios al panel. * @param pane */public void addComponentToPane(Container pane) {

debugViewManager = new DebugViewManager();//Este panel contiene la vista de desarrollo

JPanel codeJPanel = new JPanel(); //Barra de menú de la vista de desarrollo JMenuBar menuBarCodeView = new JMenuBar();

JMenu menu, submenu; JMenuItem menuItem; JToolBar toolBar; JButton button; ImageIcon icon; //A continuación definimos todas las acciones de la vista de código/desarrollo java.net.URL imageURL = Interface.class.getResource("images/window-new.png");

icon = new ImageIcon(imageURL);Action actionNuevoProyecto = new AbstractAction("Nuevo Proyecto", icon) {

/** * */private static final long serialVersionUID = 1L;

public void actionPerformed(ActionEvent e) {

projectsManager.createProject(); } };

imageURL = Interface.class.getResource("images/document-save.png");icon = new ImageIcon(imageURL);Action actionGuardar = new AbstractAction("Guardar", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

tabsManager.saveCurrentlySelectedTab(); } };

imageURL = Interface.class.getResource("images/gnome-fs-directory.png");icon = new ImageIcon(imageURL);Action actionAbrirProyecto = new AbstractAction("Abrir Proyecto", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

projectsManager.openProject(); } };

imageURL = Interface.class.getResource("images/gtk-close.png");icon = new ImageIcon(imageURL);Action actionCerrarProyecto = new AbstractAction("Cerrar Proyecto", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

projectsManager.closeProject(); } };

imageURL = Interface.class.getResource("images/document-save-as.png");icon = new ImageIcon(imageURL);Action actionGuardarComo = new AbstractAction("Guardar Como...", icon) {

226

Page 238: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

tabsManager.saveCurrentlySelectedTabAs(); } };

imageURL = Interface.class.getResource("images/stock_data-linked-table.png");icon = new ImageIcon(imageURL);Action actionGuardarTodo = new AbstractAction("Guardar Todo", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

tabsManager.saveAllTabs(); } };

imageURL = Interface.class.getResource("images/gtk-quit.png");icon = new ImageIcon(imageURL);Action actionSalir = new AbstractAction("Salir", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

System.exit(0); } };

imageURL = Interface.class.getResource("images/gtk-delete.png");icon = new ImageIcon(imageURL);Action actionEliminarFichero = new AbstractAction("Eliminar Fichero", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

//Adquirimos la información del fichero actualmente seleccionado en el árbol de ficherosProjectFile currentFile = projectsManager.getCurrentlySelectedFileInJTree();Object[] options = {"OK",

"Cancelar"};if(currentFile != null){

//Preguntamos al usuario si realmente desea eliminar el ficheroint n = JOptionPane.showOptionDialog(null, "Desea eliminar " +

currentFile.file.getName() +" del sistema?", "Confirme borrado",JOptionPane.OK_CANCEL_OPTION,

JOptionPane.QUESTION_MESSAGE, null, options, options[1]);

if(n == JOptionPane.OK_OPTION){

//Lo eliminamos de la lista de pestañas así como del árbol de ficherostabsManager.dontAskAndRemoveTab(tabsManager.searchTab(currentFile));projectsManager.removeFileFromJTree(currentFile);try{

//Eliminamos el fichero del sistema de archivos/disco duro.currentFile.file.delete();

} catch (Exception x) {problemasArea.append(x.getMessage() + "\n");

}}

} } };

imageURL = Interface.class.getResource("images/stock_compile.png");icon = new ImageIcon(imageURL);Action actionCompilar = new AbstractAction("Compilar", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

if(state.compareTo(CODEVIEW) == 0){

/* * Primero intentamos seleccionar para compilar la pestaña actual; * Si no es código o no hay ninguna pestaña seleccionada, comprobamos si hay * algún fichero de código seleccionado en el árbol de ficheros. En última instancia

227

Page 239: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

* seleccionamos el fichero de código del actual proyecto. */ProjectFile codeToCompile = null;Tab currentTab = tabsManager.getCurrentlySelectedTab();ProjectFile currentFile = projectsManager.getCurrentlySelectedFileInJTree();if(currentTab != null && currentTab.pFile.type == ProjectFile.FileType.CODE){

codeToCompile = currentTab.pFile;}else if(currentFile != null

&& currentFile.type == ProjectFile.FileType.CODE){

codeToCompile = currentFile;}else{

Project p = projectsManager.getCurrentlySelectedProject();if(p != null){

for(ProjectFile pFile: p.projectFiles){

if(pFile.type == ProjectFile.FileType.CODE){

codeToCompile = pFile;break;

}}

}}if(codeToCompile != null){

//Si el archivo ha sido modificado, preguntar si el usuario quiere guardarlo antes de compilar

tabsManager.saveIfModified(codeToCompile);//Leer el ficheroString code = "";try {

String strLine; BufferedReader br = new BufferedReader(new

FileReader(codeToCompile.file));

while((strLine = br.readLine()) != null) { code += strLine + "\n"; }}catch(Exception ex)

{ System.err.println("Error: " + ex.getMessage()); }

//Traducir a instrucciones y guardarlas en formato binariotry{

/** * Si el archivo seleccionado para compilar se llama X.ls2, esta * función añadirá al proyecto el archivo binario X.ece. */File f = projectsManager.addBinaryFromCode(codeToCompile);if(!f.exists()){

//Crear el ficherof.createNewFile();

}//Crear el código binario, guardarlo, y avisar de que todo ha ido

bien.XenonHelper.saveToBinaryFile(f,

XenonHelper.translateToInstructions(code) );problemasArea.append("Compilación de " +

codeToCompile.file.getName() +" correcta y guardada en " + f.getName() +"\n");

}catch(Exception ce){

problemasArea.append(ce.getMessage() + "\n");}

}}

} };

imageURL = Interface.class.getResource("images/stock_smart-playlist.png");icon = new ImageIcon(imageURL);Action actionDepurar = new AbstractAction("Depurar", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

//state = !state;

228

Page 240: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

if(state.compareTo(CODEVIEW) == 0){

ProjectFile codeToDebug = null;/* * Primero intentamos seleccionar para depurar la pestaña actual; * Si no es código o binario, o no hay ninguna pestaña seleccionada, comprobamos si hay * algún fichero de código seleccionado en el árbol de ficheros. En última instancia * seleccionamos el fichero de código del actual proyecto. */Tab currentTab = tabsManager.getCurrentlySelectedTab();ProjectFile currentFile = projectsManager.getCurrentlySelectedFileInJTree();if(currentTab != null && (currentTab.pFile.type == ProjectFile.FileType.CODE

|| currentTab.pFile.type == ProjectFile.FileType.BINARY)){

codeToDebug = currentTab.pFile;}else if(currentFile != null && (currentFile.type == ProjectFile.FileType.CODE ||

currentFile.type == ProjectFile.FileType.BINARY)){

codeToDebug = currentFile;}else{

Project p = projectsManager.getCurrentlySelectedProject();if(p != null){

for(ProjectFile pFile: p.projectFiles){

if(pFile.type == ProjectFile.FileType.CODE ||pFile.type ==

ProjectFile.FileType.BINARY){

codeToDebug = pFile;break;

}}

}}if(codeToDebug != null && codeToDebug.type == ProjectFile.FileType.CODE){

//Comprobar si el fichero ha sido modificado y preguntar al usuario si quiere guardarlo

tabsManager.saveIfModified(codeToDebug);//Leer el ficheroString code = "";try {

String strLine; BufferedReader br = new BufferedReader(new FileReader(codeToDebug.file));

while((strLine = br.readLine()) != null) { code += strLine + "\n"; }}catch(Exception ex)

{ System.err.println("Error: " + ex.getMessage());

problemasArea.append(ex.getMessage() + "\n"); }

//Traducirlo a instruccionesArrayList<Instruction> in = null;try{

//Cargar el programa en el gestor de la vista de depuración, y abrir dicha vista

in = XenonHelper.generateMemoryMap(XenonHelper.translateToInstructions(code));

debugViewManager.setDebugCode(in, codeToDebug.file);setTitle("CESIUS IDE - " + codeToDebug.file.getPath());state = DEBUGVIEW;

}catch(Exception ce){

System.out.println(ce.getMessage());problemasArea.append(ce.getMessage() + "\n");

}System.out.println("Debugging code: " + codeToDebug.file.getName());//Add those instructions to the debug

}else if(codeToDebug != null && codeToDebug.type == ProjectFile.FileType.BINARY){

try {//Cargar binario en la vista de depuraciónArrayList<Instruction> in =

XenonHelper.openBinaryFile(codeToDebug.file);debugViewManager.setDebugCode(in, codeToDebug.file);state = DEBUGVIEW;System.out.println("Debugging binary: " +

codeToDebug.file.getName());setTitle("CESIUS IDE - " + codeToDebug.file.getPath());

}catch(Exception x){

229

Page 241: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

System.out.println(x.getMessage());problemasArea.append(x.getMessage() + "\n");

}}

}else if(state.compareTo(DEBUGVIEW) == 0){

state = CODEVIEW;

setTitle("CESIUS IDE");}CardLayout ml = (CardLayout)(cardPanel.getLayout());//Cargar la vista actual

ml.show(cardPanel, state); } };

imageURL = Interface.class.getResource("images/stock_data-next.png");icon = new ImageIcon(imageURL);Action actionEjecutar = new AbstractAction("Ejecutar", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

Emulator sim = new Emulator();

ProjectFile codeToExecute = null;

/* * Primero intentamos seleccionar para depurar la pestaña actual; * Si no es código o binario, o no hay ninguna pestaña seleccionada, comprobamos si hay * algún fichero de código seleccionado en el árbol de ficheros. En última instancia * seleccionamos el fichero de código del actual proyecto. */Tab currentTab = tabsManager.getCurrentlySelectedTab();ProjectFile currentFile = projectsManager.getCurrentlySelectedFileInJTree();if(currentTab != null && (currentTab.pFile.type == ProjectFile.FileType.BINARY)){

codeToExecute = currentTab.pFile;}else if(currentFile != null && (currentFile.type == ProjectFile.FileType.BINARY)){

codeToExecute = currentFile;}else{

Project p = projectsManager.getCurrentlySelectedProject();if(p != null){

for(ProjectFile pFile: p.projectFiles){

if(pFile.type == ProjectFile.FileType.BINARY){

codeToExecute = pFile;break;

}}

}}

if(codeToExecute != null && codeToExecute.type == ProjectFile.FileType.BINARY){

try {//Leer las instrucciones del archivo binario y abrir el emulador.ArrayList<Instruction> in = XenonHelper.openBinaryFile(codeToExecute.file);sim.setRunCode(in);sim.setMyTitle(codeToExecute.file.getPath());System.out.println("Running binary: " + codeToExecute.file.getName());sim.setVisible(true);

}catch(Exception x){

System.out.println(x.getMessage());problemasArea.append(x.getMessage() + "\n");

}}

} }; imageURL = Interface.class.getResource("images/gtk-close.png");icon = new ImageIcon(imageURL);Action actionCerrarFichero = new AbstractAction("Cerrar Fichero", icon) {

/** * */private static final long serialVersionUID = 1L;

230

Page 242: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

public void actionPerformed(ActionEvent e) {tabsManager.closeCurrentlySelectedTab();

} };

imageURL = Interface.class.getResource("images/gtk-close.png");icon = new ImageIcon(imageURL);Action actionCerrarTodos = new AbstractAction("Cerrar Todos", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

tabsManager.closeAllTabs(); } }; Action actionLimpiarProblemas = new AbstractAction("Limpiar", null) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

problemasArea.setText(""); } };

imageURL = Interface.class.getResource("images/help.png");icon = new ImageIcon(imageURL);Action actionSobre = new AbstractAction("Sobre este programa...", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

Rectangle r = getBounds();Sobre dialog = new Sobre(r.x, r.y);dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);dialog.setVisible(true);

} }; //Creamos la barra de menú de la vista de código/desarrollo

menu = new JMenu("Archivo");menuBarCodeView.add(menu);

menuItem = menu.add(actionNuevoProyecto);menu.add(menuItem);

menu.addSeparator();

menuItem = menu.add(actionCerrarFichero);menu.add(menuItem);

menuItem = menu.add(actionCerrarTodos);menu.add(menuItem);

menuItem = menu.add(actionEliminarFichero);menu.add(menuItem);

menu.addSeparator();

menuItem = menu.add(actionGuardar);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_S, ActionEvent.CTRL_MASK));menu.add(menuItem);

menuItem = menu.add(actionGuardarComo);menu.add(menuItem);

menuItem = menu.add(actionGuardarTodo);menu.add(menuItem);

menu.addSeparator();

menuItem = menu.add(actionSalir);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, ActionEvent.CTRL_MASK));menu.add(menuItem);

//////////

menu = new JMenu("Proyecto");menuBarCodeView.add(menu);

menuItem = menu.add(actionAbrirProyecto);

231

Page 243: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

menu.add(menuItem);menuItem = menu.add(actionCerrarProyecto);menu.add(menuItem);

menu.addSeparator();

menuItem = menu.add(actionCompilar);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_B, ActionEvent.CTRL_MASK));menu.add(menuItem);menuItem = menu.add(actionDepurar);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_D, ActionEvent.CTRL_MASK));menu.add(menuItem);menuItem = menu.add(actionEjecutar);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_E, ActionEvent.CTRL_MASK));menu.add(menuItem);

///////////

menu = new JMenu("Ayuda");menuBarCodeView.add(menu);

menuItem = menu.add(actionSobre);menu.add(menuItem);

////////////

//Creamos la barra de herramientas de la vista de desarrollo

toolBar = new JToolBar();toolBar.setFloatable(false);

button = toolBar.add(actionNuevoProyecto);button.setToolTipText("Nuevo Fichero");

button = toolBar.add(actionGuardar);button.setToolTipText("Guardar");

button = toolBar.add(actionGuardarComo);button.setToolTipText("Guardar Como...");

button = toolBar.add(actionGuardarTodo);button.setToolTipText("Guardar Todo");

button = toolBar.add(actionAbrirProyecto);button.setToolTipText("Abrir Proyecto");

button = toolBar.add(actionCerrarProyecto);button.setToolTipText("Cerrar Proyecto");

button = toolBar.add(actionCompilar);button.setToolTipText("Compilar");

button = toolBar.add(actionDepurar);button.setToolTipText("Depurar");

button = toolBar.add(actionEjecutar);button.setToolTipText("Ejecutar");

////////////

/* * splitPane es un panel dividido de forma que en su parte izquierda tiene el árbol de archivos, * y en su parte derecha están las pestañas de los archivos abiertos y el panel de problemas. */

JSplitPane splitPane = new JSplitPane();splitPane.setResizeWeight(0.15);

//El árbol de archivos ha de estar dentro de un panel que permita el desplazamiento horiz/vertical.

JScrollPane scrollPane = new JScrollPane();splitPane.setLeftComponent(scrollPane);

//rightSplitPane contiene el panel de problemas y las pestañas de archivos abiertos.

JSplitPane rightSplitPane = new JSplitPane();rightSplitPane.setResizeWeight(0.8);rightSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);splitPane.setRightComponent(rightSplitPane);

JTabbedPane tabbedFilePane = new JTabbedPane(JTabbedPane.TOP);//Iniciamos el gestor de pestañastabsManager = new TabsManager(tabbedFilePane);rightSplitPane.setLeftComponent(tabbedFilePane);

projectsManager = new ProjectsManager(tabsManager);

232

Page 244: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

scrollPane.setViewportView(projectsManager.getProjectsTree());

//El panel de problemas estará dentro de una pestañaJTabbedPane tabbedPane_1 = new JTabbedPane(JTabbedPane.TOP);rightSplitPane.setRightComponent(tabbedPane_1);

problemasArea = new JTextArea();problemasArea.setEditable(false);JScrollPane scrollPane_2 = new JScrollPane(problemasArea);tabbedPane_1.addTab("Problemas", null, scrollPane_2, null);

//Creamos un menú vinculado al panel de problemas para poder vaciar dicho panelJPopupMenu popup = new JPopupMenu();popup.add(actionLimpiarProblemas);MouseListener popupListener = new PopupListener(popup);problemasArea.addMouseListener(popupListener);

//Aquí definimos la disposición gráfica de los componentes en la vista de desarrollo. GroupLayout gl_menu1 = new GroupLayout(codeJPanel); gl_menu1.setHorizontalGroup( gl_menu1.createParallelGroup(Alignment.LEADING) .addComponent(menuBarCodeView, 0, 1060, Short.MAX_VALUE) .addComponent(toolBar, 0, 1060, Short.MAX_VALUE) .addComponent(splitPane, 0, 1060, Short.MAX_VALUE) ); gl_menu1.setVerticalGroup( gl_menu1.createParallelGroup(Alignment.LEADING) .addGroup(gl_menu1.createSequentialGroup() .addComponent(menuBarCodeView, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(toolBar, GroupLayout.PREFERRED_SIZE, 24, GroupLayout.PREFERRED_SIZE) .addComponent(splitPane, 0, 560, Short.MAX_VALUE) ) ); codeJPanel.setLayout(gl_menu1); //////////////

//Panel que contendrá toda la vista de depuración. JPanel debugJPanel = new JPanel(); //Barra de menús de la vista de depuración. JMenuBar menuBarDebug = new JMenuBar();

//A continuación definimos todas las acciones de la vista de depuración.

imageURL = Interface.class.getResource("images/player_play.png");icon = new ImageIcon(imageURL);Action actionEjecutarIns = new AbstractAction("Ejecutar Instrucción", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

debugViewManager.actionExecuteNextInstruction(); } };

imageURL = Interface.class.getResource("images/player_end.png");icon = new ImageIcon(imageURL);Action actionEjecutarHasta = new AbstractAction("Ejecutar Hasta...", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

String s = (String)JOptionPane.showInputDialog( null, "Ejecutar hasta la instrucción en la posición de memoria:\n", "Introduzca dato", JOptionPane.PLAIN_MESSAGE, new ImageIcon(), null, "0");

if(s.compareTo("") != 0){

int num = Integer.parseInt(s);System.out.println("Ejecutar hasta la instrucción "+ num);if(num >= 0 && num <= Instruction.Memory_Address_Limit){

debugViewManager.actionRunTo(num);}

} } };

imageURL = Interface.class.getResource("images/reload.png");icon = new ImageIcon(imageURL);Action actionReiniciar = new AbstractAction("Comenzar de nuevo", icon) {

/**

233

Page 245: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

* */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

debugViewManager.actionRestart(); } };

imageURL = Interface.class.getResource("images/player_fwd.png");icon = new ImageIcon(imageURL);Action actionEjecutarTodo = new AbstractAction("Ejecutar Todo", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

debugViewManager.actionRun(); } };

imageURL = Interface.class.getResource("images/player_pause.png");icon = new ImageIcon(imageURL);Action actionPausar = new AbstractAction("Pausar", icon) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

debugViewManager.actionPause(); } };Action actionBinario = new AbstractAction("Binario", null) {

/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

debugViewManager.setRegistersBase(DebugViewManager.Base.BINARY); } };

Action actionDecimal = new AbstractAction("Decimal", null) {/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

debugViewManager.setRegistersBase(DebugViewManager.Base.DECIMAL); } };

Action actionHexadecimal = new AbstractAction("Hexadecimal", null) {/** * */private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {

debugViewManager.setRegistersBase(DebugViewManager.Base.HEXADECIMAL); } };

menu = new JMenu("Archivo");menuBarDebug.add(menu);

menuItem = menu.add(actionSalir);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, ActionEvent.CTRL_MASK));menu.add(menuItem);

//////////////

menu = new JMenu("Vista");menuBarDebug.add(menu);

menuItem = menu.add(actionDepurar);menuItem.setText("Salir del modo depuración");menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_F, ActionEvent.CTRL_MASK));menu.add(menuItem);

menu.addSeparator();

submenu = new JMenu("Base");

234

Page 246: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

menu.add(submenu);

submenu.add(actionBinario);

submenu.add(actionDecimal);

submenu.add(actionHexadecimal);

//////////////

menu = new JMenu("Operaciones");menuBarDebug.add(menu);

menuItem = menu.add(actionEjecutarIns);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_S, ActionEvent.CTRL_MASK));menu.add(menuItem);menuItem = menu.add(actionEjecutarHasta);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_H, ActionEvent.CTRL_MASK));menu.add(menuItem);menuItem = menu.add(actionReiniciar);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_Q, ActionEvent.CTRL_MASK));menu.add(menuItem);menuItem = menu.add(actionEjecutarTodo);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_R, ActionEvent.CTRL_MASK));menu.add(menuItem);menuItem = menu.add(actionPausar);menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_P, ActionEvent.CTRL_MASK));menu.add(menuItem);

//////////////

//Definimos la barra de herramientas de la vista de depuración.

toolBar = new JToolBar();toolBar.setFloatable(false);

button = toolBar.add(actionEjecutarIns);button.setToolTipText("Ejecutar Instrucción");button = toolBar.add(actionEjecutarHasta);button.setToolTipText("Ejecutar Hasta...");button = toolBar.add(actionReiniciar);button.setToolTipText("Comenzar de nuevo");button = toolBar.add(actionEjecutarTodo);button.setToolTipText("Ejecutar Todo");button = toolBar.add(actionPausar);button.setToolTipText("Pausar");button = toolBar.add(actionDepurar);button.setToolTipText("Salir del modo depuración");JLabel timeLabel = new JLabel(" T: ");JCheckBox checkBox = new JCheckBox();checkBox.addItemListener(debugViewManager);JLabel checkBoxLabel = new JLabel("Ejecutar en 2 pasos");time = new JLabel("000000 ms");time.setToolTipText("Tiempo de ejecución");debugViewManager.timeLabel = time;

slider = new JSlider(JSlider.HORIZONTAL, 1, 1000, 2);

slider.setToolTipText("Frecuencia del procesador");

//Etiqueta que muestra al usuario la frecuencia escogida.JLabel l = new JLabel("2 Hz");l.setToolTipText("Frecuencia del procesador");

//El listener detectará que el slider ha cambiado y modificará la frecuencia del procesadorSliderListener slistener = new SliderListener(l, debugViewManager);slider.addChangeListener(slistener);

//Este listener sirve para poder mover el slider con la rueda del ratónslider.addMouseWheelListener(new MouseWheelListener() {

@Overridepublic void mouseWheelMoved(MouseWheelEvent arg0) {

if(slider != null){

int notches = arg0.getWheelRotation(); if (notches < 0) { slider.setValue(slider.getValue() + 1); } else { slider.setValue(slider.getValue() - 1); }

}}

235

Page 247: Proyecto Fin de Carrera EMULADOR DE COMPUTADOR DIGITAL …bibing.us.es/proyectos/abreproy/12150/fichero/Emulador+de+Compu… · una descripción de las clases y métodos que contiene.

});toolBar.add(timeLabel);toolBar.add(time);toolBar.add(checkBox);toolBar.add(checkBoxLabel);toolBar.add(slider);toolBar.add(l);

//Definimos la disposición de los componentes de la vista de depuración.

GroupLayout gl_menu2 = new GroupLayout(debugJPanel); gl_menu2.setHorizontalGroup( gl_menu2.createParallelGroup(Alignment.LEADING) .addComponent(menuBarDebug, 0, 1060, Short.MAX_VALUE) .addComponent(toolBar, 0, 1060, Short.MAX_VALUE) .addComponent(debugViewManager, 0, 1060, Short.MAX_VALUE) ); gl_menu2.setVerticalGroup( gl_menu2.createParallelGroup(Alignment.LEADING) .addGroup(gl_menu2.createSequentialGroup() .addComponent(menuBarDebug, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(toolBar, GroupLayout.PREFERRED_SIZE, 24, GroupLayout.PREFERRED_SIZE) .addComponent(debugViewManager, 0, 692, Short.MAX_VALUE)) ); debugJPanel.setLayout(gl_menu2); //Instanciamos el panel que contiene ambas vistas. cardPanel = new JPanel(new CardLayout()); cardPanel.add(codeJPanel, CODEVIEW); cardPanel.add(debugJPanel, DEBUGVIEW); //Añadimos dicho panel al panel principal pane.add(cardPanel);

}

/** * @brief Lanza la aplicación */public static void main(String[] args) {

EventQueue.invokeLater(new Runnable() {public void run() {

try {Interface frame = new Interface();frame.pack();frame.setVisible(true);

} catch (Exception e) {e.printStackTrace();

}}

});}

/** * Crear el frame */public Interface() {

//core = new CesiusHelper();setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Definimos la posición en pantalla y el tamaño de la ventana.setBounds(100, 100, 1060, 750);

setTitle("CESIUS IDE");addComponentToPane(getContentPane());

}

}

236