Como no es nada del otro mundo, y muy simple, dejo aquí el código para el que quiera divertirse en completarlo.
Código: Seleccionar todo
DEFINT A-Z
DECLARE SUB RUNCPU ()
'WIDTH 80, 50
Screen 20
DIM SHARED RAM(4096): ' SOLO TIENE UN TOTAL DE 4K DE RAM!
Dim Shared RI, DIRF, PILA, PAUSA, SALIR, VK, TECLA, I$
DIM SHARED STACK(16): ' PILA DE MAXIMO DE 16 SALTOS A SUBRUTINAS
DIM SHARED V(16): ' REGISTROS DE VARIABLES DE 0 A F. LA V(F) ES LA DE ESTADOS
DIM SHARED VT(16): ' REGISTROS DE TECLAS DE 0 A F
TECLA = 255
VK = 255: ' REGISTRO DE TECLA PULSADA (DE 0 A F) (255= NINGUNA)
RI = 0: ' REGISTRO INDEXADO "I" DE 12 BITS
PILA = 0: ' DIRECCION DE LA PILA DE RETORNO (MAXIMO 16)
DIRF = &H200: ' INICIO DE PROGRAMA SIEMPRE EN LA &H200
CLS
RANDOMIZE TIMER: ' PARA LA SUBRUTINA DE NUMEROS ALEATORIOS
FOR F = 0 TO 15: V(F) = 0: NEXT: ' INICIALIZA LAS VARIABLES
' CARGA LAS FUENTES EN LA DIRECCION 0 DE LA RAM
D = 0
FOR F = 1 TO 40
READ A
RAM(D) = (A AND &HF0)
D = D + 1
RAM(D) = (A AND &HF) * 16
D = D + 1
NEXT F
FF = 0
AA = 1: BB = 1
DIM FILES$(50): ' max 50 ficheros . OJO!
SHELL "dir /B /ON games >files": ' SEGUN VERSION DEL MSDOS DE WIN98
OPEN "files" FOR INPUT AS 1
WHILE NOT EOF(1)
FF = FF + 1
LINE INPUT #1, FILES$(FF)
WEND
CLOSE 1
INICIO:
FOR F = 1 TO 48 - (48 - FF)
LOCATE F, 1: PRINT F; TAB(6); FILES$(F);
   OPEN "GAMES\" + FILES$(F) FOR BINARY ACCESS READ AS 1
   A$ = "  "
   REG& = 1
   WHILE REG& < 150
   GET #1, REG&, A$
   IF A$ = CHR$(0) + CHR$(255) THEN COLOR 6, 0: PRINT TAB(20); "SUPER CHIP8": COLOR 7, 0
   REG& = REG& + 2
   WEND
   CLOSE 1
NEXT
LOCATE AA, 6: COLOR 0, 7: PRINT FILES$(AA); : COLOR 7, 0
1
A$ = UCASE$(INKEY$): IF A$ = "" THEN GOTO 1
IF A$ = CHR$(27) THEN CLS : END
IF LEN(A$) = 2 THEN IF RIGHT$(A$, 1) = "P" THEN AA = AA + 1
IF LEN(A$) = 2 THEN IF RIGHT$(A$, 1) = "H" THEN AA = AA - 1
IF A$ = CHR$(13) THEN N$ = FILES$(AA): CLS : GOTO EMPIEZA
IF AA < 1 THEN AA = FF - 1
IF AA > FF - 1 THEN AA = 1
LOCATE AA, 6: COLOR 0, 7: PRINT FILES$(AA); : COLOR 7, 0
IF BB <> AA THEN LOCATE BB, 6: COLOR 7, 0: PRINT FILES$(BB); : BB = AA
GOTO 1
EMPIEZA:
      
       FOR F = 8 TO 80 - 7: LOCATE 1, F: PRINT CHR$(254): NEXT
       FOR F = 2 TO 33: LOCATE F, 8: PRINT CHR$(254): LOCATE F, 80 - 7: PRINT CHR$(254): NEXT
       FOR F = 8 TO 80 - 7: LOCATE 34, F: PRINT CHR$(254): NEXT
OPEN "GAMES\" + N$ FOR BINARY ACCESS READ AS 1
A$ = " "
REG& = 1
D = &H200
WHILE NOT EOF(1)
GET #1, REG&, A$: RAM(D) = ASC(A$)
D = D + 1
REG& = REG& + 1
WEND
CLOSE 1
BUCLE:
  CALL RUNCPU
       
        IF TECLA <> 255 THEN GOTO 22
 
  I$ = INKEY$
22
  IF I$ = CHR$(27) THEN SALIR = 1
     
      IF (I$ >= "0" AND I$ <= "9") = -1 THEN VK = VAL(I$)
      IF (I$ >= "A" AND I$ <= "F") = -1 THEN VK = VAL("&H" + I$)
      IF I$ = " " THEN VK = 5
      IF LEN(I$) = 2 THEN
            I$ = RIGHT$(I$, 1)
            IF I$ = "H" THEN VK = 2
            IF I$ = "P" THEN VK = 8
            IF I$ = "K" THEN VK = 4
            IF I$ = "M" THEN VK = 6
      END IF
        IF TECLA <> 255 THEN V(TECLA) = VK: TECLA = 255
  IF SALIR = 1 THEN
      ' RESET
      CLS
      DIRF = &H200
      SALIR = 0
      FOR F = 0 TO 15: V(F) = 0: NEXT: ' INICIALIZA LAS VARIABLES
      PILA = 0
      VK = 255
      RI = 0
      GOTO INICIO
  END IF
GOTO BUCLE
' DATOS DE LAS FUENTES INTERNAS (SPRITE FONTS) EN LA DIRECCION &H0
' PARA LOS CARACTERES "0" AL "9", Y "A" A "F" DE 5*8 PIXELS
DATA &Hf9,&H99,&Hf2,&H62,&H27
DATA &Hf1,&Hf8,&Hff,&H1f,&H1f
DATA &H99,&Hf1,&H1f,&H8f,&H1f
DATA &Hf8,&Hf9,&Hff,&H12,&H44
DATA &Hf9,&Hf9,&Hff,&H9f,&H1f
DATA &Hf9,&Hf9,&H9e,&H9e,&H9e
DATA &Hf8,&H88,&Hfe,&H99,&H9e
DATA &Hf8,&Hf8,&Hff,&H8f,&H88
SUB RUNCPU
' RI=REGISTRO INDEXADO
 FOR F# = 0 TO 1000: NEXT: ' PAUSA DE PRUEBAS
' CADA VEZ QUE SE EJECUTA UNA INSTRUCCION, DESCUENTA UN 1 A CONTADOR DE PAUSA
PAUSA = PAUSA - 1: : IF PAUSA < 0 THEN PAUSA = 0
OPH = RAM(DIRF)
OPL = RAM(DIRF + 1)
' SOLO DEBUG
' GOTO NODEBUG
LOCATE 35, 1
PRINT "DIRECCION:"; HEX$(DIRF); " OPCODE:"; HEX$(OPH); " "; HEX$(OPL); "   "
PRINT "RI="; HEX$(RI); "    "
PRINT "PILA="; PILA; " --> "; HEX$(STACK(PILA)); "   "
FOR F = 0 TO 7: LOCATE 40 + F, 40: PRINT "V"; HEX$(F); ":"; HEX$(V(F)); " "; V(F); "    ": NEXT
FOR F = 8 TO 15: LOCATE 40 + (F - 8), 60: PRINT "V"; HEX$(F); ":"; HEX$(V(F)); " "; V(F); "    ": NEXT
' IF DIRF > &H380 THEN A$ = INPUT$(1)
NODEBUG:
DIRF = DIRF + 2
N0 = (OPH AND &HF0) / 16
N1 = (OPH AND &HF)
N2 = (OPL AND &HF0) / 16
N3 = (OPL AND &HF)
ON N0 + 1 GOTO s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sa, sb, sc, sd, se, sf
s0:
' codigos 0 **************************************************************
  
   ' 00E0 --> CLS
   IF OPL = &HE0 THEN
       CLS
       FOR F = 8 TO 80 - 7: LOCATE 1, F: PRINT CHR$(254): NEXT
       FOR F = 2 TO 33: LOCATE F, 8: PRINT CHR$(254): LOCATE F, 80 - 7: PRINT CHR$(254): NEXT
       FOR F = 8 TO 80 - 7: LOCATE 34, F: PRINT CHR$(254): NEXT
   END IF
  
   ' 00EE --> RTS: RETORNO DE SUBRUTINA "JSR (1xxx)"
   IF OPL = &HEE THEN
        IF PILA = 0 THEN PRINT "ERROR: PILA DE RETORNO VACIA.": END
        DIRF = STACK(PILA)
        PILA = PILA - 1
        IF PILA < 0 THEN PILA = 0
   END IF
   ' 00FF --> HIGH MODE: ACTIVA MODO SUPER CHIP8 (128x64) (EN PRUEBAS)
   IF OPL = &HFF THEN
      CLS : PRINT "JUEGO DE MODO SUPER CHIP8. NO SOPORTADO POR AHORA.": A$ = INPUT$(1): SALIR = 1
   END IF
EXIT SUB
s1:
' codigos 1 **************************************************************
   ' 1xxx --> JMP: SALTO SIN RETORNO (INCONDICIONAL)
   DIRF = N1 * 256 + OPL
   
EXIT SUB
s2:
' codigos 2 **************************************************************
   ' 2xxx --> JSR: SALTO CON RETORNO (MAXIMO 16 SALTOS)
   PILA = PILA + 1
   STACK(PILA) = DIRF
   IF PILA > 16 THEN PRINT "ERROR: DESBORDAMIENTO DE LA PILA": END
   DIRF = N1 * 256 + OPL
EXIT SUB
s3:
' codigos 3 **************************************************************
  
   ' 3rxx --> SKEQ VR,XX: SALTAR SIGUIENTE DIRECCION (2 BYTES) SI VR=XX
   IF V(N1) = OPL THEN DIRF = DIRF + 2
EXIT SUB
s4:
' codigos 4 **************************************************************
   ' 4rxx --> SKNE VR,XX: SALTAR SIGUIENTE DIRECCION (2 BYTES) SI VR<>XX
   IF V(N1) <> OPL THEN DIRF = DIRF + 2
EXIT SUB
s5:
' codigos 5 **************************************************************
   ' 5ry0 --> SKEQ VR,VY: SALTAR SIGUIENTE DIRECCION (2 BYTES) SI VR=VY
   IF V(N1) = V(N2) THEN DIRF = DIRF + 2
EXIT SUB
s6:
' codigos 6 **************************************************************
   ' 6rxx --> MOV VR,XX: CARGA REGISTRO V(R) CON XX
   V(N1) = OPL
EXIT SUB
s7:
' codigos 7 **************************************************************
    ' 7rxx --> ADD VR,XX: A¥ADE A V(R) EL VALOR XX (SIN ACARREO)
    V(N1) = (V(N1) + OPL) AND &HFF
EXIT SUB
s8:
' codigos 8 **************************************************************
    ' 8ry0 --> MOV VR,VY: COPIAR VY EN VR
    IF N3 = 0 THEN V(N1) = V(N2): EXIT SUB
    ' 8ry1 --> OR VR,VY: "OREAR" VY EN VR
    IF N3 = 1 THEN V(N1) = V(N1) OR V(N2): EXIT SUB
   
    ' 8ry2 --> AND VR,VY: "ANDEAR" VY EN VR
    IF N3 = 2 THEN V(N1) = V(N1) AND V(N2): EXIT SUB
   
    ' 8ry3 --> XOR VR,VY: "XOREAR" VY EN VR
    IF N3 = 3 THEN V(N1) = V(N1) XOR V(N2): EXIT SUB
   
    ' 8ry4 --> ADD VR,VY: A¥ADIR A VR EL VY (SIN ACARREO)
    IF N3 = 4 THEN
        V(N1) = V(N1) + V(N2)
        IF V(N1) > 255 THEN V(N1) = V(N1) AND &HFF: V(&HF) = 1 ELSE V(&HF) = 0
        EXIT SUB
    END IF
    ' 8ry5 --> SUB VR,VY: RESTA A VR EL VY (VF=1 SI <0)   **(R - Y)**
    IF N3 = 5 THEN
       V(N1) = V(N1) - V(N2)
       IF V(N1) < 0 THEN V(N1) = 256 + V(N1): V(&HF) = 0 ELSE V(&HF) = 1
       EXIT SUB
    END IF
    ' 8r06 --> SHR VR: ROTA A LA DERECHA EL VR. EL BIT 0 SE CARGA EN VF
    IF N3 = 6 THEN V(&HF) = V(N1) AND 1: V(N1) = V(N1) \ 2: EXIT SUB
    ' 8ry7 --> RSB VR,VY: RESTA A VY EL VR (VF=1 SI <0)   **(Y - R)**
    IF N3 = 7 THEN
       V(N1) = V(N2) - V(N1)
       IF V(N1) < 0 THEN V(N1) = 256 + V(N1): V(&HF) = 1 ELSE V(&HF) = 0
       ' AQUI
       EXIT SUB
    END IF
   
    ' 8r0E --> SHL YR: ROTA A LA IZQUIERDA EL VR. EL BIT 7 SE CARGA EN VF
    IF N3 = &HE THEN V(&HF) = (V(N1) AND &H80) / &H80: V(N1) = (V(N1) * 2) AND &HFF
EXIT SUB
s9:
' codigos 9 **************************************************************
  
   ' 9ry0 --> SKEQ VR,VY: SALTAR SIGUIENTE DIRECCION (2 BYTES) SI VR<>VY
   IF V(N1) <> V(N2) THEN DIRF = DIRF + 2
    
EXIT SUB
sa:
' codigos a **************************************************************
   
   ' Axxx --> MVI XXX: CARGA EL INDEXADO CON XXX
   RI = N1 * 256 + OPL
EXIT SUB
sb:
' codigos b **************************************************************
   ' Bxxx --> JMI XXX : SALTA A XXX + V0 (VARIABLE 0)
   DIRF = (N1 * 256 + OPL) + V(0): ' VERIFICAR
   IF DIRF > 4096 THEN PRINT "ERROR: DIRECCION DE SALTO FUERA DE 4096": END
   
EXIT SUB
sc:
' codigos c **************************************************************
   ' Crxx --> RAND VR,XX: CARGA EN V(R) EL DATO ALEATORIO MENOR O IGUAL A XX
   V(N1) = RND(1) * OPL
   
EXIT SUB
sd:
' codigos d **************************************************************
  
   ' Drys --> SPRITE VR,VY,S : DIBUJA GRAFICO EN "VR,VY" DE ALTURA "S"
    
     X = V(N1)
     Y = V(N2)
     S = N3
     V(&HF) = 0: ' BORRA EL ACARREO
   FOR F = 0 TO S - 1
     
     A = RAM(RI + F)
     G = 256
     WHILE G <> 1
       ER = 0
       G = G / 2
       IF A AND G THEN A$ = CHR$(219) ELSE A$ = CHR$(32)
       IF Y > 31 THEN ER = 1
       IF Y < 0 THEN ER = 1
       IF X > 63 THEN ER = 1
       IF X < 0 THEN ER = 1
       IF ER = 0 THEN B = SCREEN(Y + 2, X + 9)
      
       IF (A$ = CHR$(219) AND B = 219) = -1 THEN A$ = CHR$(32): V(&HF) = 1: GOTO NOPINTAR
       IF (A$ = CHR$(219) AND B = 32) = -1 THEN A$ = CHR$(219): GOTO NOPINTAR
       IF (A$ = CHR$(32) AND B = 219) = -1 THEN A$ = CHR$(219): GOTO NOPINTAR
       IF (A$ = CHR$(32) AND B = 32) = -1 THEN A$ = CHR$(32):  GOTO NOPINTAR
NOPINTAR:
       IF ER = 0 THEN LOCATE Y + 2, X + 9: PRINT A$: X = X + 1
     WEND
     Y = Y + 1: X = V(N1)
   NEXT F
   '    AA$ = INPUT$(1)
EXIT SUB
se:
' codigos e **************************************************************
   ' Ek9E --> SKPR K: SALTAR SIGUIENTE DIRECCION (2 BYTES) SI VT(KEY)=1
   IF OPL = &H9E THEN IF V(N1) = VK THEN DIRF = DIRF + 2: VK = 255
  
   ' EkA1 --> SKUP K: SALTAR SIGUIENTE DIRECCION (2 BYTES) SI VT(KEY)=1
   ' OJO ESTAN AL REVES, ESTUDIARLO CON EL BRIX
   IF OPL = &HA1 THEN IF V(N1) = VK THEN VK = 255 ELSE DIRF = DIRF + 2
EXIT SUB
sf:
' codigos f **************************************************************
   ' Fr07 --> GDELAY VR: CARGA LA PAUSA EN VR
   IF OPL = &H7 THEN V(N1) = PAUSA: EXIT SUB
  
   ' Fr0A --> KEY VR: SE PARA EN ESPERA DE UNA TECLA A PULSAR EN VR
   IF OPL = &HA THEN
      WHILE I$ = "": I$ = UCASE$(INKEY$): WEND
      TECLA = N1: ' OBLIGA A QUE AL SALIR SE META EN V(N1) EL VALOR DE LA TECLA
      EXIT SUB
   END IF
   ' Fr15 --> SDELAY VR: ACTIVA LA PAUSA SEGUN VR
   IF OPL = &H15 THEN PAUSA = V(N1): EXIT SUB
  
   ' Fr18 --> SSOUND VR: EMITE UN SONIDO DE DURACION VR (OJO CON LA DURACION)
   IF OPL = &H18 THEN EXIT SUB: ' SOUND 500, V(N1) / 3: EXIT SUB
  
   ' Fr1E --> ADI VR: A¥ADE AL INDEXADO RI EL CONTENIDO DE VR
   IF OPL = &H1E THEN
      RI = RI + V(N1)
      IF RI > 4095 THEN RI = RI - 4096
      EXIT SUB
   END IF
  
   ' Fr29 --> FONT VR: HACE QUE EL INDEXADO RI APUNTE AL CARACTER VR
   IF OPL = &H29 THEN RI = (V(N1) AND &HF) * 5: EXIT SUB
   ' Fr33 --> BCD VR: ALMACENA EN "RI,RI+1,RI+2" EL BCD DEL VR
   IF OPL = &H33 THEN
      A$ = LTRIM$(RTRIM$(STR$(V(N1))))
      IF LEN(A$) = 1 THEN A$ = "00" + A$
      IF LEN(A$) = 2 THEN A$ = "0" + A$
      B = VAL(MID$(A$, 1, 1))
      C = VAL(MID$(A$, 2, 1))
      D = VAL(MID$(A$, 3, 1))
      RAM(RI + 0) = B
      RAM(RI + 1) = C
      RAM(RI + 2) = D
      EXIT SUB
   END IF
   ' Fr55 --> STR V0-VR: ALMACENA (PUSH) LOS REGISTROS DE V(0) A V(R) EN RI
   IF OPL = &H55 THEN
     FOR F = 0 TO N1
       RAM(RI) = V(F)
       RI = RI + 1
     NEXT
     EXIT SUB
   END IF
  
   ' Fr65 --> LDR V0-VR: RECUPERA (POP ) LOS REGISTROS DE V(0) A V(R) DE RI
   IF OPL = &H65 THEN
     FOR F = 0 TO N1
       V(F) = RAM(RI)
       RI = RI + 1
     NEXT
     EXIT SUB
   END IF
END SUB
Una captura del programa:





 
  Yo caí hace unos 6 años, y no lo cambio ya. Me vale y sobra.
 Yo caí hace unos 6 años, y no lo cambio ya. Me vale y sobra. 
  
 
  
 



