2.7 KiB
Motivación
A partir de completar el juego "Turing Complete" y tener un CPU de 8bit con arquitectura LEG funcional, me dispongo a crear un compilador para mi lenguaje "J-LANG".
Estructura del CPU
Arquitectura: 8bit PROM: 256 bytes RAM: 256 bytes STACK: 256 bytes
Direcciones
0x00 REG0 0x01 REG1 0x02 REG2 0x03 REG3 0x04 REG4 | RAM VALUE 0x05 REG5 | RAM ADDR PTR 0x06 PROGRAM COUNTER 0x07 INPUT/OUTPUT
Registros basicos
Desde: 0x00 Hasta: 0x03
Son registros que almacenan 1 byte.
Registros conectados a la RAM
Estos registros hacen de "puente" con la ram.
0x05 REG5 es el counter de la ram. 0x04 REG4 es el valor que contiene RAM[counter(0x05)]
input/output
Son 1 byte de entrada y otro de salida para interactuar con el juego "Turing Complete"
OPCODES
Las instrucciones de este cpu tienen que tener un tamaño de 4 bytes cada una. Se permiten dos modos de direccionamiento, desde un registro o modo inmediato.
- Desde registro: Se usa el byte para indicar el registro que guarda el valor
- Inmediato: Se usa el byte como valor directamente
La estructura de una instrucción es: [OPCODE] [INPUT0] [INPUT1] [TARGET]
El ultimo byte "target" indica en que registro debe guardarse el resultado de la instruccion.
En los opcodes condicionales, el ultimo byte (TARGET) indica el valor que se escribirá en el PROGRAM_COUNTER si se cumple la condicion.
======== ALU ======== 0x00 ADD r0 r1 t0 0x01 SUB r0 r1 t0 0x02 AND r0 r1 t0 0x03 OR r0 r1 t0 0x04 NOT r0 r1 t0 0x05 XOR r0 r1 t0
0x40 ADD r0 #1 t0 ; # significa inmediato 0x41 SUB r0 #1 t0 0x42 AND r0 #1 t0 0x43 OR r0 #1 t0 0x44 NOT r0 #1 t0 0x45 XOR r0 #1 t0
0x80 ADD #0 r1 t0 0x81 SUB #0 r1 t0 0x82 AND #0 r1 t0 0x83 OR #0 r1 t0 0x84 NOT #0 r1 t0 0x85 XOR #0 r1 t0
0xC0 ADD #0 #1 t0 0xC1 SUB #0 #1 t0 0xC2 AND #0 #1 t0 0xC3 OR #0 #1 t0 0xC4 NOT #0 #1 t0 0xC5 XOR #0 #1 t0 ====== CONDITIONAL ====== 0x30 EQ r0 r1 pc ; equal 0x31 NEQ r0 r1 pc ; not_equal 0x32 LS r0 r1 pc ; less 0x33 LSE r0 r1 pc ; less_or_equal 0x34 GR r0 r1 pc ; greater 0x35 GRE r0 r1 pc ; greater_or_equal ======== RAM ======== 0xE0 RAM_ST ?? ?? ?? ; store value in REG4 in REG5 position RAM[REG5] = REG4 0xE1 RAM_LD ?? ?? ?? ; no es usa en realidad, la ram siempre está haciendo output en la direccion 0x04 ====== STACK ====== 0x22 PUSH r0 ?? t0 ; ?? no se usa pero debe estar, t0 sobrescribe dicha direccion a 0 0x23 POP ?? ?? t0 0xE2 PUSH #0 ?? t0 0xE3 POP ?? ?? t0 ====== FUNCTIONS ====== 0x08 CALL r0 ?? ?? ; push de pc+1 en stack y setea pc al valor que contiene r0 0x09 RET ?? ?? ?? ; pop del stack y escribe el valor en el pc 0x88 CALL #0 0x89 RET ?? ?? ??