Buen dia
Hace mucho tiempo había un deseo de escribir un emulador de algún procesador.
¿Y qué podría ser mejor que inventar una bicicleta?
El nombre de la bicicleta es V16, por pegar la palabra Virtual y, de hecho, profundidad de bits.
Por donde empezar
Y debe comenzar, por supuesto, con una descripción del procesador.
Al principio, planeaba escribir un emulador DCPU-16, pero hay más que suficientes milagros en Internet, así que decidí centrarme solo en "lamer" lo más básico con DCPU-16 1.1.
Arquitectura
Memoria y puertos
- V16 direcciona 128Kb (65536 palabras) de RAM, que también se puede usar como búfer de dispositivo y la pila.
- La pila comienza con la dirección FFFF, por lo tanto, RSP tiene un valor estándar de 0xFFFF
- Los puertos de E / S V16 tienen 256, todos tienen una longitud de 16 bits. Leer y escribir de ellos se lleva a cabo mediante las instrucciones
IN b, a
AND OUT b, a
.
Registros
V16 tiene dos conjuntos de registros de propósito general: primario y alternativo.
Un procesador puede funcionar con un solo conjunto, por lo que puede cambiar entre conjuntos utilizando la instrucción XCR
.
Instrucciones
Todas las instrucciones tienen una longitud máxima de tres palabras y están completamente definidas primero
La primera palabra se divide en tres valores: el byte bajo es el código de operación, el byte alto en forma de dos valores de 4 bits es la descripción de los operandos.
Interrupciones
Las interrupciones aquí no son más que una tabla con direcciones en las que el procesador duplica la instrucción CALL
. Si el valor de la dirección es cero, la interrupción no hace nada, simplemente restablece el indicador de HF.
Un ejemplo de pseudocódigo y palabras en el que todo esto debería traducirse:
MOV RAX, 0xABCD ; 350D ABCD MOV [RAX], 0x1234 ; 354D 1234
Ciclos
V16 puede ejecutar una instrucción en 1, 2 o 3 medidas. Cada acceso a la memoria es un ciclo de reloj separado. ¡La instrucción no es tacto!
¡Comencemos a escribir!
Implementación de estructuras básicas de procesador.
Un conjunto de registros. Solo hay cuatro registros, pero la situación mejora porque hay dos conjuntos de este tipo en el procesador. El cambio ocurre usando la instrucción XCR
.
typedef struct Regs { uint16_t rax, rbx;
Banderas A diferencia de DCPU-16, V16 tiene saltos condicionales, llamadas de subrutina y retornos de la misma. Por el momento, el procesador tiene 8 indicadores, 5 de los cuales son indicadores de condición.
En realidad, el procesador en sí. También describe la tabla de direcciones de interrupción, que se puede llamar descriptores y encontrar otra referencia a x86.
typedef struct CPU {
Operando. Al obtener los valores, primero debemos leer, luego cambiar y luego escribir el valor donde lo obtuvimos.
typedef struct Opd { uint8_t code : 4; uint16_t value; uint16_t nextw; } opd_t;
Funciones para trabajar con estructuras.
Cuando se describen todas las estructuras, surge la necesidad de funciones que doten a estas estructuras del poder mágico del código apagado.
cpu_t * cpu_create(void);
Además, no mencioné una gran enumeración con códigos de operación, pero esto no es necesario y es necesario solo para comprender lo que está sucediendo en todo este desastre.
Función Tick ()
Además, hay llamadas a funciones estáticas destinadas únicamente a llamar desde tick()
.
void cpu_tick(cpu_t *cpu) {
¿Qué hacer a continuación?
En un intento por encontrar la respuesta a esta pregunta, reescribí el emulador cinco veces de C a C ++, y viceversa.
Sin embargo, los objetivos principales se pueden identificar ahora:
- Fije las interrupciones normales (en lugar de simplemente llamar a una función y prohibir recibir otras interrupciones, realice una llamada a la función y agregue nuevas interrupciones a la cola).
- Los dispositivos de tornillo, así como las formas de comunicarse con ellos, el beneficio de los códigos de operación puede ser 256.
- Para enseñar
No te escribas ninguna herejía sobre Habr El procesador funciona a una velocidad de reloj específica de 200 MHz.
Conclusión
Espero que este "artículo" sea útil para alguien, alguien les pedirá que escriban algo similar.
Mis pasteles se pueden ver en github .
Además, sobre el horror, tengo un ensamblador para la versión anterior de este emulador (No, ni siquiera lo intentes, el emulador al menos se quejará del formato ROM incorrecto)