Hola!
Como algunos ya saben, me he embarcado en la programación de un "
emulador" del microprocesador
Intel 8080 mediante un
PIC18F4550.
Ese es el micro que se utilizó en el famoso
Altair 8800, y -de alguna forma- es el "padre" toda la familia "x86" que aún utilizamos en nuestras PC. El
Z80 también es una "evolución" de ese micro.
Es un micro muy sencillo (
tiene ya casi 40 años sobre su espalda), con pocos registros y un "set" de 256 instrucciones. Lo que he hecho es escribir un programa en
JALv2 que va leyendo la RAM (*) e interpretando cada una de las instrucciones del ASM del 8080 que encuentra. A cada paso ajusta el valor del
Program Counter, de los registros, del registro de estado, etc, de forma que la simulación hace lo mismo que el micro real.
(*) Por ahora y para simplificar el hard, la "RAM" es un vector dentro de la memoria del PIC (256 Bytes) y el
Stack (pila) otro vector igual. Es muy simple modificar el programa para que el chip lea una memoria SRAM externa, pero al mantener el diseño simple pude ir probando todo sobre un entrenador "casero" que tengo.
Empecé el 2 de febrero a codificar las instrucciones del 8080, y terminé hoy. Luego de dos semanas de picar código,
pude realizar la prueba de fuego:
escribir un programa en el ASM del 8080 y correrlo en el PIC.El programa es muy simple: suma los números entre 15 y 0. Es este:
MVI B, 0x10
MVI A, 0x00
(restar) DCR B
JZ (fin)
ADD B
JMP (restar)
(fin)
Solo 6 instrucciones
Primero pone B = 16, luego A = 0, hace B = B - 1, si el flag "zero" del registro de estado es 1 -es decir, B = 0) salta al fina, sino suma A con B y guarda el resultado en A (A = A +
y finalmente salta a la tercer instrucción otra vez.
Una pavada, vamos! Obviamente, lo tuve que "traducir" a binario para poder cargarlo en la "RAM":
Posición de
memoria RAM Valor Instrucción/ comentario
-------------------------------------------------------------------------
0000 00000110 MVI B,
0001 00010000 0x10 (B = 10 en hexadecimal)
0002 00111110 MVI A,
0003 00000000 0x00 (A = 0)
0004 000000101 DCR B (B = B - 1)
0005 11001010 JZ
0006 00001100 12
0007 00000000 00 (Salta a 0x000C si B = 0 )
0008 10000000 ADD B (A = A +
0009 11000011 JMP
000A 00000100 04
000B 00000000 00 (Salta a la posicion de mmemoria 0x0004)
000C 00000000 NOP (Nada, fin del programa)
Solo tengo que poner en el vector "RAM []" los valores en binario. Al presionar el
reset, el programa se ejecuta desde la primer instrucción.
Increíblemente, funcionó a la primera.El siguiente vídeo -
tiene subtitulos - servirá para inmortalizar ese momento :rolleyes2:
http://www.youtube.com/watch?v=q5gfXIv-LjcBueno, eso es todo por ahora. Tengo que ponerme a
1)
Optimizar los tiempos de ejecución de cada instrucción. Lograr que cada una sea lo mas rápida posible. Estoy en un promedio de unas 35 a 45 instrucciones ASM del PIC por cada instrucción del 8080. Como el PIC corre a 12 mips, puedo ejecutar una instrucción del 8080 cada 3 o 4 millonésimas de segundo.
Eso es algo así como 300 mil instrucciones 8080/segundo. Bastante bien, ya que el micro original generalamente corria a 1 o 2 MHz y cada instrucción le lleva entre 1 y 7 ciclos de reloj. Pero creo que puede mejorarse MUCHO.
2)
Una vez que esté depurado, debo hacer que cada instrucción demore lo que debe. Es decir, deberé "
nivelar" los tiempos para que la ejecución del programa sea realista, y que un
CALL demore 3 veces mas que un
CDR (por decir algo).
3) Cuando eso esté listo, armaré una placa con 64KB de SRAM, el PIC, y.....a hacer pruebas más interesantes
Saludos.