Página principal
Mi primer microprocesador emulado.
 
arduino
8bits
CORE CPU_S8


Desde el primer momento que vi emular el Spectrum en un PC 386, mi admiración empezó por estos tipos de programas. Siempre había pensado en hacer un microcontrolador emulado, el que yo conocía es el Z80, hace muchos años había creado un ensamblador del Z80 en el SBASIC del QL. Pero mi intención era que corriese en un arduino, y visto que el arduino tiene solo 2K de RAM, se hace difícil su eficacia en cuanto utilización y velocidad,  aunque he visto alguno que se ha atrevido.
Lo cierto es que me puse como reto crear un microprocesador de 8bits que solo tuviera un direccionamiento de 8bits (256 bytes).
Mas pequeño imposible, tengo que meter el programa, las variables y la pila en 256bits.


CORE CPU_S8


La estructura del microprocesador es de los mas simple.
4 R0-R1-R2-R3  .Registros simples, que además se pueden utilizar como registros de direccionamiento de memoria.
1 PC - Registro de contador de programa.
1 SP - Registro de dirección de Pila.
1 RII - Registro de dirección de interrupción interna.  No implementado
1 RIE - Registro de dirección de interrupción externa.  No implementado
1 RS - Registro de estado.   S-Signo     Z- Cero   C- Acarreo
1 RSI - Registro de estado de interrupciones.  No implementado.

Una memoria RAM de 256 bytes donde se carga el programa a ejecutar.
El programa se empieza a ejecutar en la posición de memoria 0.
Lo normal es que el registro de pila se carga inicialmente con la dirección 255, pero se puede cambiar al gusto de cada uno.

Con estas premisas me plantee crear un juego de instrucciones, normalmente de un solo byte, pero hay unas cuantas de 2 bytes que son la que precisan de un dato inmediato.


Ejemplo de instrucciones de 1 byte


Ejemplo de instrucciones de 2 bytes

Para ver todo el juego de instrucciones que he implementado ver documento INSTRUCCIONES.
El emulador está realizado en C , con lo cual se consigue una portabilidad casi inmediata desde el PC al arduino.
En el PC el emulador funciona bastante rápido, en el arduino funciona bien, aunque la diferencia entre la velocidad de uno y del otro es abismal. El PC funciona a 2Ghz y el arduino a 16Mhz ese es el motivo fundamental.
La decodificación de instrucciones se realiza mediante switch code , case 0....... . Aunque los compiladores realizan un buen trabajo en la búsquedas de opciones case:  , el tener que buscar continuamente códigos, ralentiza mucho el emulador.
En una próxima versión utilizaré tablas de funciones que son mucho mas rápido.

Aunque se pudiera pensar que la realización del emulador es difícil, no lo es tanto, es laboriosa,  tienes que implementar una por una todas las instrucciones.

El problema de crear tu propio microprocesador virtual es que no tienes entorno de trabajo, no tienes ensamblador ni desensamblador. Tampoco tienes un programa que transfiera el código binario al arduino.
Diría que del tiempo empleado en este proyecto, el 20% lo he utilizado en crear el emulador del microprocesador virtual.
Entre el ensamblador, el preprocesador incluido en el ensamblador, el desensamblador, y el programa que transfiere el código al arduino me ha llevado el 80% del tiempo.

El formato utilizado en las instrucciones es:  MOV RegistroOrigen , RegistroDestino
El preprocesador pasa todo a mayúsculas, no hace diferencia entre mayúsculas y minúsculas.
Debo decir que el ensamblador solo admite números en formato decimal, este será otro de los cambios a realizar.

Los puertos de entrada y salida están mapeados, es decir, el puerto 0 del microprocesador virtual esta mapeado para que apunte al puerto PORTB (0x05) de microcontrolador ATmega328.

/ * MAPEO DE PUERTO EN ARDUINO
/ * 0 PORTB 0X05
/ * 1 PORTC 0X08
/ * 2 PORTD 0X0B
/ * 3 PINB 0X03
/ * 4 PINC 0X06
/ * 5 PIND 0X09
/ * 6 DDRB 0X04
/ * 7 DDRC 0X07
/ * 8 DDRD 0X0A


Ejemplo normal de la creación de una aplicación.

      ./ensam blink.asm -o blink.bin        //ensambla el fichero blink.asm
      ./core8 blink.bin -p2                 //prueba en el emulador del PC
      ./sendData blink.bin /dev/ttyUSB0     //manda el programa al arduino par se ejecute

      ./disam blink.bin                     //desensamblador del fichero.


Preprocesador y ensamblador core8 V_3_5
========================================
/ comentario
$ variable
# variable de salto

Formato:
$variable
  nemotécnico  <- Dos espacios mínimo desde principio de linea

 
Números solo en formato decimal.



Desensamblador  V_3_5
======================
 ./disam fichero.bin
    opciones:
        -pt Salida por pantalla
        -o nombre fichero.asm



Core8 V3_5
===========
Antes de mandar el programa al arduino se puede probar en el emulador del core8 en el PC.


./core fichero.bin
    opciones:
        -t Tiempo entre operaciones
        -p1 Imprimir borrando pantalla
        -p2 Imprimir solo puertos



sendData V3_5
==============
Manda el programa al arduino para que ejecute el emulador del core8 en el arduino.

./senData fichero.bin /dev/ttyUSB0



El primer programa que se suele hacer con microprocesadores es el hacer parpadear un LED.
En este caso hacemos parpadear el LED que tiene el arduino en el pin D13.
/ blink

/ * MAPEO DE PUERTO EN ARDUINO
/ * 0 PORTB 0X05
/ * 1 PORTC 0X08
/ * 2 PORTD 0X0B
/ * 3 PINB 0X03
/ * 4 PINC 0X06
/ * 5 PIND 0X09
/ * 6 DDRB 0X04
/ * 7 DDRC 0X07
/ * 8 DDRD 0X0A

$retardo 250
$portb 0
$setportb 6

#setup
    mov 255,r0      /puerto b como salida
    out $setportb
    clear r0
    mov $portb,r1
#volver
    mov 32 , r0
    out r0,(r1)
    wait $retardo
    wait $retardo
    clear r0
    out r0,(r1)
    wait $retardo
    wait $retardo
    jmp #volver
   
    stop   
    end

A este programa blink.asm  le he quitado los retardo y he conseguido una onda cuadrada de 60KHz, con esto deberíamos ver la velocidad de emulador.

Para que el arduino cargue el programa en RAM , debemos instalar el programa cargador en el arduino, se llama arduV3_5.
El programa se instala en el arduino y después de 3 destellos, espera al código procedente del PC.


DOCUMENTACIÓN
PROGRAMAS
VIDEO

Con 240 bytes de código se puede hacer poco, pero era el reto que creo que he conseguido.
Todo el proyecto ha sido bastante laborioso, es fruto del confinamiento por el COVI-19, hay que sacar algo positivo de todo esto.
El entorno de trabajo fue Debian10 64bits.

Saludos.
Juan Galaz