Mi CPU teórica...
Publicado: 18 Ene 2013, 08:07
Buenas!
Sigo con mi cabezonería de diseñar un ordenador virtual que funcione (ver hilo viewtopic.php?nomobile=1&f=15&t=680), pariéndolo desde cero, pero que sea completamente "real" en cuanto a su funcionamiento, comportamiento, etc...
He utilizado GLBasic para programar esta "tontería", aquí adjunto mis notas y el código fuente usado a la hora de desarrollar las interioridades de la CPU, con el tema de registros, interpretación del opcode, asignación de RAM y video (utilizo una zona de la Ram, como en el ZX)... sin querer me he visto diseñando mi propio ensamblador para el "aparato", etc...
De momento, tengo pocos opcodes que funcionen, ya que he ido añadiendo a medida que "pensaba" en lo que iba a necesitar...
Le he dado muy poca RAM (256 bytes) y en esta tengo 64 bytes para video (matriz de 8x8) a lo meggy RGB, y lo que resta para código en sí...
Seguro que muchos pensaréis que estoy perdiendo el tiempo y/o que esto es una chorrada... puede ser... pero personalmente creo que me esta ayudando bastante a entender COMO se diseñan los micros, etc...
Acepto todo tipo de pedradas...
y consejos de los que ya habéis hecho emuladores...
Saludos
Sigo con mi cabezonería de diseñar un ordenador virtual que funcione (ver hilo viewtopic.php?nomobile=1&f=15&t=680), pariéndolo desde cero, pero que sea completamente "real" en cuanto a su funcionamiento, comportamiento, etc...
He utilizado GLBasic para programar esta "tontería", aquí adjunto mis notas y el código fuente usado a la hora de desarrollar las interioridades de la CPU, con el tema de registros, interpretación del opcode, asignación de RAM y video (utilizo una zona de la Ram, como en el ZX)... sin querer me he visto diseñando mi propio ensamblador para el "aparato", etc...
De momento, tengo pocos opcodes que funcionen, ya que he ido añadiendo a medida que "pensaba" en lo que iba a necesitar...
Le he dado muy poca RAM (256 bytes) y en esta tengo 64 bytes para video (matriz de 8x8) a lo meggy RGB, y lo que resta para código en sí...
Seguro que muchos pensaréis que estoy perdiendo el tiempo y/o que esto es una chorrada... puede ser... pero personalmente creo que me esta ayudando bastante a entender COMO se diseñan los micros, etc...
Acepto todo tipo de pedradas...

Saludos
Código: Seleccionar todo
// --------------------------------- //
// Project: Maquina
// Start: Saturday, December 29, 2012
// IDE Version: 11.171
RAM 256 bits
VideoRAM dir: #128 - 64 bits
-------------------------------------------------------v2
Instrucción: Word (+ ValorA) (+ ValorB)
Word 8 bits: 000 00 00 0 (DESTINO - ORIGEN) - Reservado
op A B R
Opcodes:
1- 000 // NOP (pausa)
2- 001 // SET A,B
3- 010 // JMP A (#direccion)
4- 011 //
5- 100 //
6- 101 //
7- 110 //
8- 111 //
A:
1- 00 // Valor Real
2- 01 // PosRAM
3- 10 // RegX
4- 11 // RegY
B:
1- 00 // Valor Real
2- 01 // PosRAM
3- 10 // RegX
4- 11 // RegY
-------------------------------------------------------
if opcode=0 then NOP
if opcode=1 then SET
if opcode=2 then JMP
SET A,B: DESTINO ORIGEN PC
001 00 00 0 - SET ValorReal,ValorReal -> ERROR
001 01 00 0 - SET PosRAM,ValorReal -> RAM[ValorA]=ValorB -> ram valorB -> 3
001 10 00 0 - SET RegX,ValorReal -> RegX=ValorA -> regX valorA -> 2
001 11 00 0 - SET RegY,ValorReal -> RegY=ValorA -> regY valorA -> 2
001 00 01 0 - SET ValorReal,PosRAM -> ERROR
001 01 01 0 - SET PosRAM,PosRAM -> RAM[ValorA]=RAM[ValorB] -> ram ram -> 3
001 10 01 0 - SET RegX,PosRAM -> RegX=RAM[ValorA] -> regX ram -> 2
001 11 01 0 - SET RegY,PosRAM -> RegY=RAM[ValorA] -> regY ram -> 2
001 00 10 0 - SET ValorReal,RegX -> ERROR
001 01 10 0 - SET PosRAM,RegX -> RAM[ValorA]=RegX -> ram regX -> 2
001 10 10 0 - SET RegX,RegX -> RegX=RegX -> regX regX -> 1
001 11 10 0 - SET RegY,RegX -> RegY=RegX -> regY regX -> 1
001 00 11 0 - SET ValorReal,RegY -> ERROR
001 01 11 0 - SET PosRAM,RegY -> RAM[ValorA]=RegY -> ram regY -> 2
001 10 11 0 - SET RegX,RegY -> RegX=RegY -> regX regY -> 1
001 11 11 0 - SET RegY,RegY -> RegY=RegY -> regY regY -> 1
JMP A:
010 00 00 0 - JMP ValorReal -> PC=RAM[ValorA] -> 2
010 01 00 0 - JMP PosRAM -> PC=RAM[ValorA] -> 2
010 10 00 0 - JMP RegX -> PC=RegX -> 1
010 11 00 0 - JMP RegY -> PC=RegY -> 1
-------------------------------------------------------
PROGRAMA:
NOP 000 00 00 0 -> 0
SET #128,1 001 01 00 0 10000000 00000001 -> 40,128,1
SET #137,1 001 01 00 0 10001001 00000001 -> 40,137,1
NOP 000 00 00 0 -> 0
SET #146,1 001 01 00 0 10010010 00000001 -> 40,146,1
SET RegX,RegY 001 10 11 0 -> 54
SET RegY,0 001 11 00 0 00000000 -> 56,0
NOP 000 00 00 0 -> 0
SET #155,RegX 001 01 10 0 10011011 -> 44,155
SET #128,RegY 001 01 11 0 10000000 -> 46,128
SET RegX,64 001 10 00 0 01000000 -> 48,173
SET RegX,#137 001 10 01 0 -> 50,137
JMP #0 010 00 00 0 -> 64,0
-------------------------------------------------------
Organización RAM:
1 2
2 5
0 8 5
[------------------------|-------------]
B V T
Código: Seleccionar todo
// ---------------------------------------------------------- Prepara entorno GLBasic
CLEARSCREEN
SETSCREEN 800,600,0
SYSTEMPOINTER TRUE
SETTRANSPARENCY RGB(255,0,255)
SETCURRENTDIR("Media")
LOADFONT "font/Terminal_Default_Font_5x12_Blanco.png",0
LOADFONT "font/Terminal_Default_Font_5x12_Rojo.png",1
SETFONT 0
// ---------------------------------------------------------- Variables Maquina
GLOBAL dtime
GLOBAL fps
GLOBAL delay
GLOBAL tick
GLOBAL estado=1
GLOBAL ciclo=0
GLOBAL posram=0
GLOBAL dato=0
GLOBAL datobin$=""
GLOBAL PC=0
GLOBAL ContPC=0
GLOBAL Opcode=0
GLOBAL TipoA=0
GLOBAL TipoB=0
GLOBAL ValorA=0
GLOBAL ValorB=0
GLOBAL RegX=11
GLOBAL RegY=22
GLOBAL TipoOrigen
GLOBAL TipoDestino
GLOBAL ValorOrigen
GLOBAL ValorDestino
// ---------------------------------------------------------- Declaración Hardware
GLOBAL RAM[]
DIM RAM[256]
GLOBAL dirvideoRAM=128
reset()
// ---------------------------------------------------------- Maid Loop
WHILE estado=1
reloj()
IF tick=1 AND ciclo=0 // FETCH
ContPC=RAM[PC]
PC=PC+1
datobin$=Dec2Bin$(ContPC)
Opcode=Bin2Dec(MID$(datobin$,0,3))
TipoA=Bin2Dec(MID$(datobin$,3,2))
TipoB=Bin2Dec(MID$(datobin$,5,2))
ciclo=1 // -> DECODE
tick=0
delay=0
ENDIF
IF tick=1 AND ciclo=1 // DECODE
decodifica()
ciclo=2 // -> SET RESULTADO
tick=0
delay=0
ENDIF
IF tick=1 AND ciclo=2 // -> SET RESULTADO
actualiza()
ciclo=0 // -> FETCH
tick=0
delay=0
ENDIF
render()
interface()
WEND
FUNCTION reset:
REDIM RAM[0]
REDIM RAM[256]
PC=0
ContPC=0
Opcode=0
TipoA=0
TipoB=0
ValorA=0
ValorB=0
RegX=11
RegY=22
ciclo=0
dtime=0
carga_programa()
ENDFUNCTION
FUNCTION carga_programa:
RAM[0]=0
RAM[1]=40
RAM[2]=128
RAM[3]=1
RAM[4]=40
RAM[5]=137
RAM[6]=1
RAM[7]=0
RAM[8]=40
RAM[9]=146
RAM[10]=1
RAM[11]=54
RAM[12]=56
RAM[13]=0
RAM[14]=0
RAM[15]=44
RAM[16]=155
RAM[17]=46
RAM[18]=128
RAM[19]=48
RAM[20]=173
RAM[21]=50
RAM[22]=137
RAM[23]=64
RAM[24]=0
//NOP 000 00 00 0 -> 0
//SET #128,1 001 01 00 0 10000000 00000001 -> 40,128,1
//SET #137,1 001 01 00 0 10001001 00000001 -> 40,137,1
//NOP 000 00 00 0 -> 0
//SET #146,1 001 01 00 0 10010010 00000001 -> 40,146,1
//SET RegX,RegY 001 10 11 0 -> 54
//SET RegY,0 001 11 00 0 00000000 -> 56,0
//NOP 000 00 00 0 -> 0
//SET #155,RegX 001 01 10 0 10011011 -> 44,155
//SET #128,RegY 001 01 11 0 10000000 -> 46,128
//SET RegX,173 001 10 00 0 01000000 -> 48,173
//SET RegX,#137 001 10 01 0 -> 50,137
//JMP #0 010 00 00 0 -> 64,0
ENDFUNCTION
FUNCTION reloj:
LOCAL VelociadCPU=10 //250
dtime = GETTIMER()
fps = ((1000/dtime)+fps)/2
delay=delay+dtime
IF delay>VelociadCPU // 1 sec
delay=0
IF tick=0
tick=1
ELSE
tick=0
ENDIF
ENDIF
ENDFUNCTION
FUNCTION render:
CLEARSCREEN
PRINT "MAQUINA: ciclo: "+ciclo,0,(15*0)
PRINT "PC: "+PC,0,(15*1)
PRINT "ContPC: "+ContPC,0,(15*2)
PRINT "datobin$: "+datobin$,0,(15*3)
PRINT "Opcode: "+Opcode+" "+TipoA+","+TipoB,0,(15*4)
PRINT "Reg X: "+RegX,300,(15*1)
PRINT "Reg Y: "+RegY,300,(15*2)
LOCAL px=200
LOCAL py=10
LOCAL dot=8
LOCAL peekRAM=dirvideoRAM
FOR y=0 TO 7
FOR x=0 TO 7
IF RAM[peekRAM]=0
DRAWRECT px+(x*dot),py+(y*dot),dot-1,dot-1,RGB(100,0,0) // LED OFF
ELSE
DRAWRECT px+(x*dot),py+(y*dot),dot-1,dot-1,RGB(200,0,0) // LED ON
ENDIF
peekRAM=peekRAM+1
NEXT
NEXT
SHOWSCREEN
ENDFUNCTION
FUNCTION interface:
IF KEY(45)=1 THEN reset() // X Reset
ENDFUNCTION
FUNCTION actualiza:
IF Opcode=1 // SET
IF TipoDestino=1 // ->RAM
IF TipoOrigen=1 //RAM
RAM[ValorDestino]=RAM[ValorOrigen]
ENDIF
IF TipoOrigen=2 //ValorREAL
RAM[ValorDestino]=ValorOrigen
ENDIF
IF TipoOrigen=3 //RegX
RAM[ValorDestino]=RegX
ENDIF
IF TipoOrigen=4 //RegY
RAM[ValorDestino]=RegY
ENDIF
ENDIF
IF TipoDestino=2 // ->ValorREAL - ERROR
ENDIF
IF TipoDestino=3 // ->RegX
IF TipoOrigen=1 //RAM
RegX=RAM[ValorDestino]
ENDIF
IF TipoOrigen=2 //ValorREAL
RegX=ValorDestino
ENDIF
IF TipoOrigen=3 //RegX
RegX=RegX
ENDIF
IF TipoOrigen=4 //RegY
RegX=RegY
ENDIF
ENDIF
IF TipoDestino=4 // ->RegY
IF TipoOrigen=1 //RAM
RegY=RAM[ValorDestino]
ENDIF
IF TipoOrigen=2 //ValorREAL
RegY=ValorDestino
ENDIF
IF TipoOrigen=3 //RegX
RegY=RegX
ENDIF
IF TipoOrigen=4 //RegY
RegY=RegY
ENDIF
ENDIF
ENDIF
IF Opcode=2 //JMP
IF TipoDestino=1 //PosRAM OK
PC=ValorDestino
ENDIF
IF TipoDestino=2 //RegX
PC=RegX
ENDIF
IF TipoDestino=3 //RegY
PC=RegY
ENDIF
ENDIF
ENDFUNCTION
FUNCTION decodifica:
IF Opcode=2 //JMP
TipoDestino=0
ValorDestino=0
IF TipoA=0 //ValorREAL
ValorA=RAM[PC]
PC=PC+1
TipoDestino=1
ValorDestino=ValorA
ENDIF
IF TipoA=1 //PosRAM
ValorA=RAM[PC]
PC=PC+1
TipoDestino=1
ValorDestino=ValorA
ENDIF
IF TipoA=2 //RegX
TipoDestino=2
ENDIF
IF TipoA=3 //RegY
TipoDestino=3
ENDIF
ENDIF
IF Opcode=1 //SET
TipoOrigen=0 // 1 RAM - 2 ValorReal - 3 RegX - 4 RegY
TipoDestino=0 // 1 RAM - 2 ValorReal - 3 RegX - 4 RegY
ValorOrigen=0
ValorDestino=0
ValorA=0
ValorB=0
IF TipoA=0 AND TipoB=0 // ValorReal,ValorReal
ENDIF
IF TipoA=1 AND TipoB=0 // PosRAM,ValorReal
TipoOrigen=2
TipoDestino=1
ValorA=RAM[PC]
PC=PC+1
ValorB=RAM[PC]
PC=PC+1
ValorOrigen=ValorB
ValorDestino=ValorA
ENDIF
IF TipoA=2 AND TipoB=0 // RegX,ValorReal
TipoOrigen=2
TipoDestino=3
ValorA=RAM[PC]
PC=PC+1
ValorDestino=ValorA
ENDIF
IF TipoA=3 AND TipoB=0 // RegY,ValorReal
TipoOrigen=2
TipoDestino=4
ValorA=RAM[PC]
PC=PC+1
ValorDestino=ValorA
ENDIF
IF TipoA=0 AND TipoB=1 // ValorReal,PosRAM
ENDIF
IF TipoA=1 AND TipoB=1 // PosRAM,PosRAM
TipoOrigen=1
TipoDestino=1
ValorA=RAM[PC]
PC=PC+1
ValorB=RAM[PC]
PC=PC+1
ValorOrigen=ValorB
ValorDestino=ValorA
ENDIF
IF TipoA=2 AND TipoB=1 // RegX,PosRAM
TipoOrigen=1
TipoDestino=3
ValorA=RAM[PC]
PC=PC+1
ValorDestino=ValorA
ENDIF
IF TipoA=3 AND TipoB=1 // RegY,PosRAM
TipoOrigen=1
TipoDestino=4
ValorA=RAM[PC]
PC=PC+1
ValorDestino=ValorA
ENDIF
IF TipoA=0 AND TipoB=2 // ValorReal,RegX
ENDIF
IF TipoA=1 AND TipoB=2 // PosRAM,RegX
TipoOrigen=3
TipoDestino=1
ValorA=RAM[PC]
PC=PC+1
ValorDestino=ValorA
ENDIF
IF TipoA=2 AND TipoB=2 // RegX,RegX
TipoOrigen=3
TipoDestino=3
ENDIF
IF TipoA=3 AND TipoB=2 // RegY,RegX
TipoOrigen=3
TipoDestino=4
ENDIF
IF TipoA=0 AND TipoB=3 // ValorReal,RegY
ENDIF
IF TipoA=1 AND TipoB=3 // PosRAM,RegY
TipoOrigen=4
TipoDestino=1
ValorA=RAM[PC]
PC=PC+1
ValorDestino=ValorA
ENDIF
IF TipoA=2 AND TipoB=3 // RegX,RegY
TipoOrigen=4
TipoDestino=3
ENDIF
IF TipoA=3 AND TipoB=3 // RegY,RegY
TipoOrigen=4
TipoDestino=4
ENDIF
ENDIF
ENDFUNCTION