CHIP-8 es un lenguaje de programación interpretado , desarrollado por Joseph Weisbecker . Fue utilizado inicialmente en el VIP COSMAC y telmac 1800 de 8 bits microordenadores a mediados de la década de 1970. Los programas CHIP-8 se ejecutan en una máquina virtual CHIP-8 . Se hizo para permitir que los videojuegos se programen más fácilmente para estas computadoras.
Aproximadamente quince años después de la introducción del CHIP-8, aparecieron intérpretes derivados para algunos modelos de calculadoras gráficas (desde finales de la década de 1980 en adelante, estos dispositivos portátiles tienen en muchos sentidos más potencia de cálculo que la mayoría de las microcomputadoras de mediados de la década de 1970 para aficionados).
Una comunidad activa de usuarios y desarrolladores existía a fines de la década de 1970, comenzando con el boletín de noticias "VIPer" de ARESCO, cuyos primeros tres números revelaron el código de máquina detrás del intérprete CHIP-8. [1]
Aplicaciones de CHIP-8
Hay varios videojuegos clásicos portados a CHIP-8, como Pong , Space Invaders , Tetris y Pac-Man . También hay aplicaciones como un generador de laberintos aleatorios y Game of Life de Conway .
Extensiones y variaciones de CHIP-8
Durante las décadas de 1970 y 1980, los usuarios de CHIP-8 compartieron programas de CHIP-8, pero también cambios y extensiones al intérprete de CHIP-8, en el boletín de noticias de los usuarios de COSMAC VIP, la revista VIPER. Estas extensiones incluyeron CHIP-10 y CHIP-8 de alta resolución, que introdujeron una resolución más alta que el estándar 64x32, y CHIP-8C y CHIP-8X, que ampliaron las capacidades de pantalla monocromática para admitir colores limitados, entre otras características. [2] Estas extensiones eran en su mayoría compatibles con versiones anteriores, ya que se basaban en el intérprete original, aunque algunos códigos de operación reutilizados rara vez usaban para nuevas instrucciones. [3]
En 1979, Electronics Australia publicó una serie de artículos sobre la construcción de un equipo de computadora similar al COSMAC VIP, basado en la arquitectura Motorola 6800 . [4] Esta computadora, la DREAM 6800, vino con su propia versión de CHIP-8. Se utilizó un boletín similar a VIPER, llamado DREAMER [5] , para compartir juegos de CHIP-8 para este intérprete. En 1981, Electronics Today International (ETI) publicó una serie de artículos sobre la construcción de una computadora, la ETI-660, que también era muy similar a la VIP (y usaba el mismo microprocesador). ETI ejecutó columnas ETI-660 regulares y CHIP-8 generales [6] hasta 1985.
En 1990, se creó un intérprete CHIP-8 llamado CHIP-48 para las calculadoras gráficas HP-48 para que los juegos pudieran programarse más fácilmente. Erik Bryntse luego creó otro intérprete basado en CHIP-48, llamado SCHIP, S-CHIP o Super-Chip. SCHIP extendió el lenguaje CHIP-8 con una resolución más grande y varios códigos de operación adicionales destinados a facilitar la programación. [7] Si no fuera por el desarrollo del intérprete CHIP-48, CHIP-8 no sería tan conocido hoy en día. [ cita requerida ]
El emulador, desensamblador y documentación técnica extendida de David Winter popularizó CHIP-8 / SCHIP en muchas otras plataformas. Presentaba una lista completa de códigos de operación y características indocumentados [8] , y se distribuía en muchos foros de aficionados. Muchos emuladores utilizaron estos trabajos como punto de partida.
Sin embargo, CHIP-48 cambió sutilmente la semántica de algunos de los códigos de operación, y SCHIP continuó usando esa nueva semántica además de cambiar otros códigos de operación. Muchos recursos en línea sobre CHIP-8 propagan esta nueva semántica, por lo que muchos juegos modernos de CHIP-8 no son compatibles con el intérprete CHIP-8 original para COSMAC VIP, incluso si no usan específicamente las nuevas extensiones SCHIP. [9]
CHIP-8 hoy
Existe una implementación de CHIP-8 para casi todas las plataformas, así como algunas herramientas de desarrollo. Los juegos todavía se están desarrollando y catalogando para CHIP-8 en la actualidad, además de los juegos más antiguos que resurgen en línea en archivos digitales. [10] [11]
Si bien CHIP-8 y SCHIP se han implementado comúnmente como emuladores , también existe una implementación de hardware puro (escrito en el lenguaje Verilog ) para ciertas placas FPGA .
Descripción de la máquina virtual
Memoria
CHIP-8 se implementó más comúnmente en sistemas 4K, como Cosmac VIP y Telmac 1800. Estas máquinas tenían 4096 (0x1000) ubicaciones de memoria, todas de 8 bits (un byte ), que es donde se originó el término CHIP-8. . Sin embargo, el propio intérprete CHIP-8 ocupa los primeros 512 bytes del espacio de memoria en estas máquinas. Por esta razón, la mayoría de los programas escritos para el sistema original comienzan en la ubicación de memoria 512 (0x200) y no acceden a la memoria debajo de la ubicación 512 (0x200). Los 256 bytes superiores (0xF00-0xFFF) están reservados para la actualización de la pantalla, y los 96 bytes por debajo de eso (0xEA0-0xEFF) se reservaron para la pila de llamadas, uso interno y otras variables.
En las implementaciones modernas de CHIP-8, donde el intérprete se ejecuta de forma nativa fuera del espacio de memoria de 4K, no es necesario evitar los 512 bytes de memoria más bajos (0x000-0x200), y es común almacenar datos de fuentes allí.
Registros
CHIP-8 tiene 16 8- bits de datos de registros nombrados V0 a VF. El registro VF también sirve como bandera para algunas instrucciones; por lo tanto, debe evitarse. En una operación de suma, VF es la bandera de acarreo , mientras que en la resta, es la bandera de "no pedir prestado". En la instrucción de dibujo, VF se establece en caso de colisión de píxeles.
El registro de direcciones, que se denomina I, tiene 16 bits de ancho y se utiliza con varios códigos de operación que involucran operaciones de memoria.
La pila
La pila solo se usa para almacenar direcciones de retorno cuando se llaman subrutinas . La versión original de RCA 1802 asignó 48 bytes para hasta 12 niveles de anidamiento; [12] las implementaciones modernas suelen tener más. [13] [14]
Temporizadores
CHIP-8 tiene dos temporizadores. Ambos cuentan hacia atrás a 60 hercios , hasta llegar a 0.
- Temporizador de retardo: este temporizador está diseñado para cronometrar los eventos de los juegos. Su valor se puede configurar y leer.
- Temporizador de sonido: este temporizador se utiliza para efectos de sonido. Cuando su valor es distinto de cero, se emite un pitido.
Aporte
La entrada se realiza con un teclado hexadecimal que tiene 16 teclas que van de 0 a F. Las teclas '8', '4', '6' y '2' se utilizan normalmente para la entrada direccional. Se utilizan tres códigos de operación para detectar la entrada. Uno omite una instrucción si se presiona una tecla específica, mientras que otro hace lo mismo si no se presiona una tecla específica . El tercero espera a que se presione una tecla y luego la almacena en uno de los registros de datos.
Gráficos y sonido
La resolución de pantalla original del CHIP-8 es de 64 × 32 píxeles y el color es monocromo . Los gráficos se dibujan en la pantalla únicamente dibujando sprites , que tienen 8 píxeles de ancho y pueden tener de 1 a 16 píxeles de alto. Los píxeles de Sprite son XOR 'd con los píxeles de pantalla correspondientes. En otras palabras, los píxeles de sprites que se configuran cambian el color del píxel de pantalla correspondiente, mientras que los píxeles de sprites no configurados no hacen nada. La bandera de acarreo (VF) se establece en 1 si los píxeles de la pantalla se cambian de armado a desarmado cuando se dibuja un objeto y, en caso contrario, se establece en 0. Se utiliza para la detección de colisiones.
Como se describió anteriormente, se reproduce un pitido cuando el valor del temporizador de sonido es distinto de cero.
Tabla de código de operación
CHIP-8 tiene 35 códigos de operación , todos de dos bytes de longitud y big-endian almacenados . Los códigos de operación se enumeran a continuación, en hexadecimal y con los siguientes símbolos:
- NNN: dirección
- NN: constante de 8 bits
- N: constante de 4 bits
- X e Y: identificador de registro de 4 bits
- PC: Contador de programas
- I: registro de 16 bits (para dirección de memoria) (similar al puntero vacío);
- VN: Una de las 16 variables disponibles. N puede ser de 0 a F (hexadecimal);
Ha habido muchas implementaciones del conjunto de instrucciones CHIP-8 desde 1978. La siguiente especificación se basa en la especificación SUPER-CHIP de 1991 (pero sin los códigos de operación adicionales que brindan funcionalidad extendida), ya que ese es el conjunto de extensiones más comúnmente encontrado en la actualidad. . Las notas a pie de página indican incompatibilidades con el conjunto de instrucciones CHIP-8 original de 1978.
Código de operación | Tipo | C Pseudo | Explicación |
---|---|---|---|
0NNN | Llamada | Llama a la rutina de código de máquina ( RCA 1802 para COSMAC VIP) en la dirección NNN. No es necesario para la mayoría de las ROM. | |
00E0 | Monitor | disp_clear() | Limpia la pantalla. |
00EE | Flujo | return; | Vuelve de una subrutina. |
1NNN | Flujo | goto NNN; | Salta a la dirección NNN. |
2NNN | Flujo | *(0xNNN)() | Llama a la subrutina en NNN. |
3XNN | Cond | if(Vx==NN) | Omite la siguiente instrucción si VX es igual a NN. (Por lo general, la siguiente instrucción es un salto para omitir un bloque de código); |
4XNN | Cond | if(Vx!=NN) | Omite la siguiente instrucción si VX no es igual a NN. (Por lo general, la siguiente instrucción es un salto para omitir un bloque de código); |
5XY0 | Cond | if(Vx==Vy) | Omite la siguiente instrucción si VX es igual a VY. (Por lo general, la siguiente instrucción es un salto para omitir un bloque de código); |
6XNN | Const | Vx = N | Establece VX en NN. |
7XNN | Const | Vx += N | Agrega NN a VX. (La bandera de transporte no se cambia); |
8XY0 | Assig | Vx=Vy | Establece VX en el valor de VY. |
8XY1 | BitOp | Vx=Vx|Vy | Establece VX en VX o VY. (Operación OR bit a bit); |
8XY2 | BitOp | Vx=Vx&Vy | Establece VX en VX y VY. (Operación AND bit a bit); |
8XY3 [a] | BitOp | Vx=Vx^V | Establece VX en VX xo VY. |
8XY4 | Matemáticas | Vx += V | Agrega VY a VX. VF se establece en 1 cuando hay acarreo y en 0 cuando no lo hay. |
8XY5 | Matemáticas | Vx -= V | VY se resta de VX. VF se establece en 0 cuando hay un préstamo y en 1 cuando no lo hay. |
8XY6 [a] | BitOp | Vx>>=1 | Almacena el bit menos significativo de VX en VF y luego desplaza VX a la derecha en 1. [b] |
8XY7 [a] | Matemáticas | Vx=Vy-Vx | Establece VX en VY menos VX. VF se establece en 0 cuando hay un préstamo y en 1 cuando no lo hay. |
8XYE [a] | BitOp | Vx<<=1 | Almacena el bit más significativo de VX en VF y luego desplaza VX a la izquierda en 1. [b] |
9XY0 | Cond | if(Vx!=Vy) | Omite la siguiente instrucción si VX no es igual a VY. (Por lo general, la siguiente instrucción es un salto para omitir un bloque de código); |
ANNN | MEM | I = NN | Establece I en la dirección NNN. |
BNNN | Flujo | PC=V0+NN | Salta a la dirección NNN más V0. |
CXNN | Rand | Vx=rand()&N | Establece VX en el resultado de una operación bit a bit y en un número aleatorio (normalmente: 0 a 255) y NN. |
DXYN | Disp | draw(Vx,Vy,N) | Dibuja un objeto en la coordenada (VX, VY) que tiene un ancho de 8 píxeles y una altura de N + 1 píxeles. Cada fila de 8 píxeles se lee con un código de bits a partir de la ubicación de memoria I; El valor no cambia después de la ejecución de esta instrucción. Como se describió anteriormente, VF se establece en 1 si cualquier píxel de la pantalla se cambia de configurado a no configurado cuando se dibuja el sprite, y en 0 si eso no sucede. |
EX9E | KeyOp | if(key()==Vx) | Omite la siguiente instrucción si se presiona la tecla almacenada en VX. (Por lo general, la siguiente instrucción es un salto para omitir un bloque de código); |
EXA1 | KeyOp | if(key()!=Vx) | Omite la siguiente instrucción si no se presiona la tecla almacenada en VX. (Por lo general, la siguiente instrucción es un salto para omitir un bloque de código); |
FX07 | Temporizador | Vx = get_delay() | Configura VX al valor del temporizador de retardo. |
FX0A | KeyOp | Vx = get_key() | Se espera una pulsación de tecla y luego se almacena en VX. (Operación de bloqueo. Todas las instrucciones se detienen hasta el próximo evento clave); |
FX15 | Temporizador | delay_timer(Vx) | Establece el temporizador de retardo en VX. |
FX18 | Sonar | sound_timer(Vx) | Establece el temporizador de sonido en VX. |
FX1E | MEM | I +=V | Agrega VX a I. VF no se ve afectado. [C] |
FX29 | MEM | I=sprite_addr[Vx] | Establece I en la ubicación del sprite para el personaje en VX. Los caracteres 0-F (en hexadecimal) se representan con una fuente de 4x5. |
FX33 | BCD | set_BCD ( Vx ) * ( I + 0 ) = BCD ( 3 ); * ( I + 1 ) = BCD ( 2 ); * ( I + 2 ) = BCD ( 1 ); | Almacena la representación decimal codificada en binario de VX, con el más significativo de los tres dígitos en la dirección en I, el dígito del medio en I más 1 y el dígito menos significativo en I más 2. (En otras palabras, tome la representación decimal de VX, coloque el dígito de las centenas en la memoria en la ubicación en I, el dígito de las decenas en la ubicación I + 1 y el dígito de las unidades en la ubicación I + 2.); |
FX55 | MEM | reg_dump(Vx,&I) | Almacena V0 a VX (incluido VX) en la memoria comenzando en la dirección I. El desplazamiento de I aumenta en 1 para cada valor escrito, pero I en sí no se modifica. [D] |
FX65 | MEM | reg_load(Vx,&I) | Llena V0 a VX (incluido VX) con valores de la memoria que comienzan en la dirección I. El desplazamiento de I aumenta en 1 para cada valor escrito, pero I en sí no se modifica. [D] |
Notas
- ^ a b c d Los códigos de operación lógicos 8XY3, 8XY6, 8XY7 y 8XYE no se documentaron en la especificación CHIP-8 original, ya que todos los códigos de operación 8000 se enviaron a instrucciones en la ALU de 1802 y no se ubicaron en el intérprete mismo; estos tres códigos de operación adicionales fueron, por lo tanto, una funcionalidad presuntamente involuntaria.
- ^ a b Los códigos de operación de CHIP-8 8XY6 y 8XYE (las instrucciones de desplazamiento de bits), que de hecho eran códigos de operación no documentados en el intérprete original, cambiaron el valor en el registro VY y almacenaron el resultado en VX. En cambio, las implementaciones de CHIP-48 y SCHIP ignoraron VY y simplemente cambiaron VX. [9]
- ^ La mayoría de las instrucciones FX1E de los intérpretes de CHIP-8 no afectan a VF, con una excepción: el intérprete de CHIP-8 para el Commodore Amiga establece VF en 1 cuando hay un desbordamiento de rango (I + VX> 0xFFF) y en 0 cuando hay no es. [15] ¡ El único juego conocido que depende de este comportamiento es Spacefight 2091! mientras que al menos un juego, Animal Race, depende de que VF no se vea afectado.
- ^ a b En la implementación original de CHIP-8, y también en CHIP-48, se deja incrementado I después de que se haya ejecutado esta instrucción. En SCHIP, me quedo sin modificar.
Referencias
- ^ " VIPER para propietario VIP de RCA" . Diario de máquinas inteligentes ( InfoWorld ) . InfoWorld Media Group. 1978-12-11. pag. 9 . Consultado el 30 de enero de 2010 .
- ^ https://github.com/mattmikolay/chip-8/wiki/CHIP%E2%80%908-Extensions-Reference
- ^ https://github.com/trapexit/chip-8_documentation
- ^ https://archive.org/stream/EA1979/EA%201979-05%20May#page/n85/mode/2up
- ^ https://archive.org/details/dreamer_newsletter_01/mode/2up
- ^ https://archive.org/stream/ETIA1981/ETI%201981-11%20November#page/n113/mode/2up
- ^ https://github.com/Chromatophore/HP48-Superchip
- ^ http://vanbeveren.byethost13.com/stuff/CHIP8.pdf
- ^ a b https://github.com/JohnEarnest/Octo/blob/gh-pages/docs/SuperChip.md#compatibility
- ^ https://johnearnest.github.io/chip8Archive/
- ^ https://rcastudio2.blogspot.com/
- ^ Manual de instrucciones de RCA COSMAC VIP CDP18S711 . Somerville: División de estado sólido de RCA. 1978. p. 36.
- ^ "Referencia técnica Chip-8 de Cowgod" . devernay.free.fr . Consultado el 3 de febrero de 2020 .
- ^ Mikolay, Matthew. "Dominando CHIP-8: Subrutinas" . mattmik.com . Consultado el 3 de febrero de 2020 .
- ^ https://github.com/Chromatophore/HP48-Superchip/issues/2
Otras lecturas
- "Manual de instrucciones de RCA COSMAC VIP CDP18S711", División de estado sólido de RCA, Somerville, NJ 08776, febrero de 1978. Parte VIP-311. págs. 13-18, 35-37.
- Revista BYTE , diciembre de 1978 , págs. 108-122. "Un sistema de programación fácil", por Joseph Weisbecker . Describe CHIP-8 con un ejemplo específico de un cohete y un juego de galería de disparos de ovnis.
- Archivo de Chip8.com Sitio web dedicado a CHIP-8 y sistemas relacionados. Mantiene la colección más completa de programas CHIP-8 en la red.
- Dominando CHIP-8 , una referencia precisa al conjunto de instrucciones CHIP-8 original
- Emulador de CHIP-8 de David Winter , utilidades y juegos.
- BytePusher Una máquina virtual minimalista inspirada en el CHIP-8.
- Grupo RCA COSMAC en Yahoo , con escaneos autorizados de la revista VIPER.
- OChip8 Un emulador de CHIP-8 en un navegador
- Dream 6800 El popular microordenador Dream 6800 presentado en Electronics Australia en 1979 ejecutó CHIP-8.
- FPGA SuperChip Una implementación de Verilog de la especificación SCHIP.
- Octo es un IDE, sistema de desarrollo, compilador / ensamblador y emulador CHIP-8 en línea, con un lenguaje de scripting patentado
- Referencia técnica de Cowgod's Chip-8 (CHIP-48 / SCHIP)
- Referencia de extensiones de Matt Mikolay CHIP-8
- CHIP-8.com Manual de computadora CHIP-8 Classic