Emulador Intel 8080. 19º IOCCC. Best of Show.
Este programa emula un procesador completo Intel(r) 8080, junto con un teletipo y un controlador de discos, tal como al inicio de la revolución de las computadoras personales (alrededor de 1975).
Aquí está el código fuente, escrito en lenguaje C:
                               #include <stdio.h>
           #define n(o,p,e)=y=(z=a(e)%16 p x%16 p o,a(e)p x p o),h(
                                #define s 6[o]
             #define p z=l[d(9)]|l[d(9)+1]<<8,1<(9[o]+=2)||++8[o]
                                #define Q a(7)
           #define w 254>(9[o]-=2)||--8[o],l[d(9)]=z,l[1+d(9)]=z>>8
                               #define O )):((
                  #define b (y&1?~s:s)>>"\6\0\2\7"[y/2]&1?0:(
                               #define S )?(z-=
                    #define a(f)*((7&f)-6?&o[f&7]:&l[d(5)])
                               #define C S 5 S 3
                       #define D(E)x/8!=16+E&198+E*8!=x?
                             #define B(C)fclose((C))
                       #define q (c+=2,0[c-2]|1[c-2]<<8)
                          #define m x=64&x?*c++:a(x),
                         #define A(F)=fopen((F),"rb+")
                    unsigned char o[10],l[78114],*c=l,*k=l
                          #define d(e)o[e]+256*o[e-1]
#define h(l)s=l>>8&1|128&y|!(y&255)*64|16&z|2,y^=y>>4,y^=y<<2,y^=~y>>1,s|=y&4
+64506; e,V,v,u,x,y,z,Z; main(r,U)char**U;{

     { { { } } }       { { { } } }       { { { } } }       { { { } } }
    { { {   } } }     { { {   } } }     { { {   } } }     { { {   } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
    { { {   } } }    { { {     } } }    { { {   } } }    { { {     } } }
      { { ; } }      { { {     } } }      { { ; } }      { { {     } } }
    { { {   } } }    { { {     } } }    { { {   } } }    { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
    { { {   } } }     { { {   } } }     { { {   } } }     { { {   } } }
     { { { } } }       { { { } } }       { { { } } }       { { { } } }

                                   for(v A((u A((e A((r-2?0:(V A(1[U])),"C")
),system("stty raw -echo min 0"),fread(l,78114,1,e),B(e),"B")),"A")); 118-(x
=*c++); (y=x/8%8,z=(x&199)-4 S 1 S 1 S 186 S 2 S 2 S 3 S 0,r=(y>5)*2+y,z=(x&
207)-1 S 2 S 6 S 2 S 182 S 4)?D(0)D(1)D(2)D(3)D(4)D(5)D(6)D(7)(z=x-2 C C C C
C C C C+129 S 6 S 4 S 6 S 8 S 8 S 6 S 2 S 2 S 12)?x/64-1?((0 O a(y)=a(x) O 9
[o]=a(5),8[o]=a(4) O 237==*c++?((int (*)())(2-*c++?fwrite:fread))(l+*k+1[k]*
256,128,1,(fseek(y=5[k]-1?u:v,((3[k]|4[k]<<8)<<7|2[k])<<7,Q=0),y)):0 O y=a(5
),z=a(4),a(5)=a(3),a(4)=a(2),a(3)=y,a(2)=z O c=l+d(5) O y=l[x=d(9)],z=l[++x]
,x[l]=a(4),l[--x]=a(5),a(5)=y,a(4)=z O 2-*c?Z||read(0,&Z,1),1&*c++?Q=Z,Z=0:(
Q=!!Z):(c++,Q=r=V?fgetc(V):-1,s=s&~1|r<0) O++c,write(1,&7[o],1) O z=c+2-l,w,
c=l+q O p,c=l+z O c=l+q O s^=1 O Q=q[l] O s|=1 O q[l]=Q O Q=~Q O a(5)=l[x=q]
,a(4)=l[++x] O s|=s&16|9<Q%16?Q+=6,16:0,z=s|=1&s|Q>159?Q+=96,1:0,y=Q,h(s<<8)
O l[x=q]=a(5),l[++x]=a(4) O x=Q%2,Q=Q/2+s%2*128,s=s&~1|x O Q=l[d(3)]O x=Q  /
128,Q=Q*2+s%2,s=s&~1|x O l[d(3)]=Q O s=s&~1|1&Q,Q=Q/2|Q<<7 O Q=l[d(1)]O s=~1
&s|Q>>7,Q=Q*2|Q>>7 O l[d(1)]=Q O m y n(0,-,7)y) O m z=0,y=Q|=x,h(y) O m z=0,
y=Q^=x,h(y) O m z=Q*2|2*x,y=Q&=x,h(y) O m Q n(s%2,-,7)y) O m Q n(0,-,7)y)  O
m Q n(s%2,+,7)y) O m Q n(0,+,7)y) O z=r-8?d(r+1):s|Q<<8,w O p,r-8?o[r+1]=z,r
[o]=z>>8:(s=~40&z|2,Q=z>>8) O r[o]--||--o[r-1]O a(5)=z=a(5)+r[o],a(4)=z=a(4)
+o[r-1]+z/256,s=~1&s|z>>8 O ++o[r+1]||r[o]++O o[r+1]=*c++,r[o]=*c++O z=c-l,w
,c=y*8+l O x=q,b z=c-l,w,c=l+x) O x=q,b c=l+x) O b p,c=l+z) O a(y)=*c++O r=y
,x=0,a(r)n(1,-,y)s<<8) O r=y,x=0,a(r)n(1,+,y)s<<8))));
system("stty cooked echo"); B((B((V?B(V):0,u)),v)); }
Como compilarlo
Primero descargue el código fuente desde aquí. Se requiere un sistema compatible con *NIX.
Para compilarlo utilice:
    cc toledo2.c -o toledo2
Se requiere una imagen inicial de memoria para hacer algo útil, así que anexo encontrará dos archivos (c_basic.bin y c_bios.bin). Renombre c_basic.bin a C y ejecute el emulador, y ¡et voila! tiene usted el Palo Alto Tiny BASIC de dominio público (por Li-Chen Wang), publicado en el antiquísimo primer volumen de la ahora desaparecida revista Dr. Dobb's Journal.
Teclee usando mayúsculas, aquí hay tres programas de ejemplo, oprima Enter después de cada línea:
   10 PRINT "Hello, world!"
   LIST
   RUN

   10 FOR A=1 TO 10       10 INPUT A
   20 PRINT A             20 INPUT B
   30 NEXT A              30 PRINT A+B
   LIST                   LIST
   RUN                    RUN
Oprima Ctrl+Z para salir, por cierto, el error de segmentación en este punto es normal.
Todos los buenos programadores comenzaron aprendiendo BASIC, ahora, ¿qué tal un emulador CP/M?
Descargue el siguiente archivo (no incluído debido a posible copyright y bla, bla):
  http://www.retroarchive.org/cpm/os/KAYPROII.ZIP
Extraiga CPM64.COM del directorio SOURCE, y copielo a archivos nombrados A y B (estos serán los discos duros). Ahora renombre el archivo c_bios.bin a C y ejecute el emulador.
¡Ahora tiene un sistema CP/M funcional!, con dos archivos en el disco A:, HALT.COM para detener el emulador (y asegurarse de que cierre los discos) e IMPORT.COM para introducir nuevos archivos.
Para obtener un sistema CP/M completo, necesitará los siguientes archivos del directorio SOURCE de KAYPROII.ZIP:
  ASM.COM  DDT.COM   DUMP.COM   ED.COM   LOAD.COM
  PIP.COM  STAT.COM  SUBMIT.COM XSUB.COM
Para importarlos, debe ejecutar el emulador con un argumento, por ejemplo:
  prog DDT.COM
Cuando aparezca la petición A>, escriba:
  IMPORT DDT.COM
Cuando termine, haga HALT, así el archivo es salvado, y puede continuar el proceso con otro archivo.
Hasta este momento he probado exitosamente el siguiente software de www.retroarchive.org:
  http://www.retroarchive.org/cpm/lang/c80v30.zip
  http://www.retroarchive.org/cpm/lang/Mbasic.com
  http://www.retroarchive.org/cpm/business/MULTPLAN.ZIP
  http://www.retroarchive.org/cpm/cdrom/CPM/UTILS/ARC-LBR/UNARC16.ARK
  http://www.retroarchive.org/cpm/cdrom/CPM/UTILS/ARC-LBR/UNARC16.MSG
  http://www.retroarchive.org/cpm/cdrom/CPM/UTILS/ARC-LBR/DELBR12.ARK
  http://www.retroarchive.org/cpm/cdrom/CPM/UTILS/SQUSQ/USQ-20.COM
  http://www.retroarchive.org/cpm/cdrom/CPM/UTILS/SQUSQ/UNCR8080.LBR
  http://www.retroarchive.org/cpm/cdrom/CPM/UTILS/DIRUTL/XDIR3-12.LBR
  http://www.retroarchive.org/cpm/cdrom/CPM/UTILS/DIRUTL/CU.LBR
  http://www.retroarchive.org/cpm/cdrom/CPM/UTILS/FILCPY/SWEEP40.LBR
Algunos programas requieren instalación para configurar la terminal, busque ANSI o VT-100.
El emulador ejecutando Wordstar bajo CP/M
El emulador ejecutando Wordstar bajo CP/M.
¿Qué es un 8080?
Sencillamente el hermano menor del Zilog Z80, no tiene registros extendidos (AF', BC', DE', HL', IX or IY), no tiene saltos relativos, y cada instrucción que comienza con CB, DD, ED o FD no existe.
Las banderas son únicamente S (Signo, bit 7), Z (Cero, bit 6), P (Paridad, bit 2) y C (Acarreo, bit 0).
Transportándolo
Es fácil si su plataforma tiene getch/kbhit y terminal ANSI
    read    -->  Z=kbhit()?getch():0
    write   -->  putchar(7[o])
    system  -->  nada
También añada lo siguiente para bloquear Ctrl-C:
    #include <signal.h>
    signal(SIGINT, SIG_IGN);
En PC/DOS puede requerir añadir ANSI.SYS a CONFIG.SYS
En *NIX el min 0 en stty es requerido, alrededor del año 2001 no era requerido.
Como trabaja (aguafiestas)
El arreglo l contiene la memoria de 64K, y es inicializado con una imagen de arranque cargada del archivo 'C', el contador de programa es el apuntador c, y los registros están en o[]. El bucle principal lee cada código de operación y lo separa en una de tres formas comunes, muchos operados trinarios seleccionan la instrucción.
   o[0] = Registro B   o[1] = Registro C
   o[2] = Registro D   o[3] = Registro E
   o[4] = Registro H   o[5] = Registro L
   o[6] = Banderas     o[7] = A o acumulador
Las siguientes instrucciones realizan operación de periféricos:
   76           Termina el emulador
   DB 00        Lee estatus de tecla oprimida
   DB 01        Lee tecla
   DB 02        Lee byte de archivo (Carry=Fin de archivo)
   D3 xx        Escribe byte de acumulador a consola
   ED ED 02     Lee un sector
   ED ED 03     Escribe un sector

   Direcciones de memoria:

   FBFA . Dirección baja fuente/destino
   FBFB - Dirección alta fuente/destino
   FBFC - Sector
   FBFD - Cilindro (byte bajo)
   FBFE - Cilindro (byte alto)
   FBFF - Unidad.
El BIOS está especialmente diseñado para este emulador, y ayuda a simplificarlo.
Otras notas:
Última modificación: 11-ago-2009
Powered by 110MB Hosting
[ Remove Footer ]