Cómo sacar audio por un pin de la FPGA (II)
En esta segunda parte hablaré de cómo elegir el orden del modulador sigma-delta y de cómo establecer el tamaño de los registros.
El rango dinámico de nuestra señal
Si queremos sacar una señal de audio de 8 bits, nuestra señal tendrá -evidentemente- 8 bits. Pero, si tenemos dos canales de 8 bits, la señal pasa a ser de 9 bits cuando los sumamos. Si tenemos tres canales de 8 bits, la señal será aun de 10 bits, pero con cuatro canales mantenemos los 10 bits. El número de bits que nos hacen falta sin redondeo es por tanto:
n = log( ch * max_ch, 2 )
Es decir, el logaritmo en base 2 del número de canales (ch) multiplicado por la amplitud máxima del canal (max_ch). Si los canales tienen un número de bits distinto (por ejemplo, algunos canales provienen de un módulo tipo PSG -AY-3-8910 o similar- y otros vienen de un módulo FM -tipo JT12-) tendremos que pensar un poco más cómo determinar el número de bits de la suma, pero la idea es la misma: que haya suficientes bits para representar la suma simultánea del valor máximo de todos los canales.
Bien, ese es el criterio conservador. El problema que tiene es que en la práctica los picos de sonido no ocurren exactamente al mismo tiempo. ¡En los generadores de sonido FM es prácticamente imposible hacerlos coincidir aun queriendo! Si los canales no coinciden en tiempo pero estamos haciendo hueco para ellos, el resultado es que las señales de cada canal aparecen más pequeñas y se oye todo más bajo. Yo recomiendo seguir un criterio mixto.
Canales PSG: estos canales proceden de sonido de onda cuadrada: o amplitud máxima o mínima alternándose. Por su forma el que se sumen valores máximos de todos los canales a la vez ocurrirá a menudo. Para ellos seguimos la fórmula anterior. Así, si tenemos 4 canales de 8 bits cada uno, necesitaremos 10 bits en total.
Canales FM: estos canales proceden de un sintetizador FM, tipo Yamaha OPx. Para ellos consideraremos esta fórmula menos restrictiva:
n = log( sqrt(ch) * max_ch, 2 )
Donde usamos la raiz del número de canales. Así por ejemplo para el JT12, con 6 canales de 9 bits tendríamos que la suma necesita 11 bits, en vez de 12 bits. Puede parecer una tontería pero un bit de más significa que la señal suene 6dB más baja.
Al usar menos bits de los estrictamente necesarios tendremos que usar un limitador, para asegurarnos de que el valor final no desborda la lógica. Un limitador produce sonido más tolerable que una inversión de fase, como ocurriría si hay desbordamiento.
El limitador, en concepto, es una sentencia similar a esta:
assign limitado = sinlimite>limite ? limite : limitado;
Selección del modulador
Siguiendo con la limitación que tenemos en la FPGA de usar un pin de salido como DAC, o sea un DAC de 1 bit, tenemos que decidir el orden del modulador sigma delta. De nuevo, siguiendo las notas de Gabor C. Temes, tenemos un resultado práctico de la relación señal-ruido según el orden L del modulador.
Si en la sección anterior habíamos calculado que necesitábamos 10 bits de señal, el SQNR si usáramos un DAC normal de 10 bits sería:
SQNR = 6 n + 1,8 = 61,8 dB
Ahora usamos la gráfica para encontrar la pareja L/OSR (OSR=OverSampling Ratio, ver entrada anterior) que más nos convenga. Y aunque en principio todo vale, hay un par de limitaciones:
- Los sigma delta de orden 1 producen tonos audibles para señales de poca amplitud y frecuencia
- Los sigma delta de orden superior a 2 son difíciles de estabilizar
- El sigma delta de orden 2 es estable para señales no demasiado grandes
Si no queremos complicarnos demasiado la vida, lo sensato es usar un sigma delta de 2º orden y ajustar el OSR para que según la gráfica podamos sacar los bits necesarios. Recordad que el OSR nos fija la interpolación de la señal de entrada, según lo ya explicado. En este ejemplo, para 10 bits necesitaríamos L=2 y OSR=32. Es decir, que si la frecuencia de muestreo original es 55kHz, la frecuencia del sigma delta será de 1,76MHz. Como vemos, no es demasiado alta.
Para un caso más extremo, de 16 bits, necesitaríamos L=2 y OSR=256, o sea 14MHz, aun asumible. No es recomendable apurar el OSR más allá de lo necesario por el numero de bits. Primero porque más resolución que la original no vas a conseguir. Y segundo porque el DAC de 1 bit que usamos (nuestro sufrido pin de la FPGA) empezará a presentar formas de onda más feas, con mayor contenido en frecuncias altas, que no nos ayudarán a un mejor sonido. Además de las mayores exigencias del interpolador para seguir subiendo el OSR.
Con esta guía deberíamos tener ya claro el OSR a usar y el interpolador que necesitaremos. En la siguiente entrada hablaré de cómo diseñar el modulador sigma delta para evitar problemas de rango de señal.
Cómo sacar audio por un pin de la FPGA (I)
Muchas placas de desarrollo FPGA vienen con una salida de audio, pero sin conversor DAC. Y lo que es peor, los dos principales sistemas de recreación retro: MiST y ZX-UNO tampoco llevan conversor DAC. ¿Por qué? Pues por la popular idea de que se puede hacer un DAC decente con un solo pin de la FPGA. Esto tiene parte de mito y parte de realidad.
El mito es que se puede hacer básicamente con un contador y con un filtro RC en el pin de la FPGA. Lo conectas directamente a los altavoces y auriculares y a correr.
La parte de realidad es que efectivamente, se puede hacer. Pero para tener un sonido limpio, fidedigno y con buena resolución hay que gastar bastantes recursos de la FPGA y hay que contar con un filtro analógico que no es tan sencillo.
En esta entrada voy a repasar la teoría y explicar cómo está implementado esto en el JT12 (mi clon verilog del YM2612). La teoría la he estudiado en Understanding Delta-Sigma Data Converters, escrito por un antiguo compañero de Analog Devices: Richard Schreier y el profesor de universidad G.C. Temes, que puso sus notas aquí. Algunas imágenes de estas entradas están sacadas de dichas notas.
Primero empezamos con lo que ha de ser la cadena de señal:
Tenemos la señal digital original con una frecuencia de muestreo fN que entra en un interpolador, luego en un bucle de moldeado de ruido (por traducir así el noise-shaping loop que es el nombre para los moduladores sigma-delta) y de ahí a un DAC para acabar en un filtro paso bajo.
Las implementaciones de muchos sistemas retro en FPGA se saltan el interpolador, omiten consideraciones de pitidos y demás del moldeado de ruido y usan un filtro RC simple como filtro final paso bajo. Vamos a ver qué son estas omisiones:
El interpolador
Todo el meollo de los sigma-delta se basa en tener un convertidor que opera a una frecuencia mucho mayor que la tasa de refresco original y que -de alguna manera- consigue que el espectro de la señal original queda respetado pese a que aparentemente hay muy poca resolución en bits.
Pero si la frecuencia de muestreo original es fN y el convertidor funciona a OSR•fN (OSR es un número que decidimos nosotros) ¿Entonces cómo cambio la frecuencia de muestreo? Bueno, pues lo que hace mucha gente es no hacer nada. O sea, cogen su señal digital que sale de un bloque que va a x kilohercios y se lo meten a uno (el DAC sigmadelta) que va a x megahercios. El resultado es que inadvertidamente han duplicado el espectro de la señal a lo largo de todo el ancho de frecuencias. La figura a) corresponde a esto.
Una forma intuitiva de entender este efecto es que si en la señal original teníamos un 1 (uno), y una muestra después un 0 (cero), con una tasa de muestreo de 50kHz, significaba que la señal cambiaba de 1 a 0 en 1/50kHz=20μs. Si entonces cambiamos la frecuencia de muestreo a 10MHz manteniendo la misma ristra de bits original a base de repetir los valores cuanto haga falta, tendremos la misma transición de 1 a 0, pero en esta ocasión ocurrirá en sólo 1/10MHz=0.1μs. Es decir, que la señal analógica original que estamos representando se vuelve mucho más rápida, con mayor contenido en frecuencias altas. De nuevo, la figura a) corresponde a esto.
Si no hacemos nada pues, el sigma delta tendrá que trabajar con todo el espectro. Incluyendo todas esas réplicas de la señal que nos interesa. Es verdad que el filtro analógico final ha de tener como frecuencia de corte fB, o sea, el ancho de banda original. Sin embargo los filtros no son perfectos y aun menos los que se usan en placas FPGA sencillas. Así que por una parte estamos complicando el trabajo del filtro analógico. Pero por otra –y quizá más importante- estamos permitiendo que estas imágenes se mezclen hacía abajo en frecuencia durante la conversión porque el sigma delta no es un proceso lineal. Así que estos espectros repetidos acabarán produciendo ruido y en el peor de los casos hasta tonos perfectamente audibles.
¿Qué tenemos que hacer entonces? La respuesta es filtrar las repeticiones. Y aquí hay muchas opciones. Mi preferida es comenzar por evitarlas desde el principio usando un interpolador lineal. Básicamente consiste en dos pasos:
- Si vamos a subir la frecuencia de muestreo un factor N, entonces debemos producir una secuencia nueva que empieza por el valor de la secuencia original, y va seguido de N-1 valores nulos. O sea, que añadimos N-1 ceros entre las muestras originales.
- Ahora esa señal nueva la pasamos por un filtro agresivo, que deje pasar la fB original y rechace las frecuencias más altas. Esto se suele hacer con filtros FIR.
En otra entrada próxima detallaremos el proceso con ejemplos. El caso es que ahora hemos pasado de la frecuencia de muestreo original a una N veces mayor. Como el sigma delta suele ir a frecuencias bastante más altas si intentamos hacer el paso de una frecuencia a la otra en una sola etapa nos encontramos con que nos hace falta un filtro FIR muy largo. Dividiendo el proceso en varios pasos acortamos el tamaño total de los filtros. Además, en algunos pasos podemos usar filtros más sencillos, como los de media onda o los sinc.
¿Y el filtro analógico? Este es el otro gran olvidado. Resulta que la publicidad de los sigma delta nos ha hecho creer que cualquier churro de filtro basta. Y no es así si queremos calidad. Fijaos en que el modulador sigma delta necesita un DAC. Estamos usando como DAC de 1 bit el pin de salida de la FPGA. ¿Y sabéis qué pinta tienen las transiciones de 1 a 0 y viceversa de ese pin? Pues sí, muy feas. Son transiciones con oscilaciones amortiguadas o con rampas lentas o con ruido acoplado de otras etapas… Todo ese ruido se lo estamos encomendando al filtro RC para que lo quite. Y no lo quitará todo. Y aunque sea en general de alta frecuencia -por encima de lo audible- en cuanto aparezca un amplificador por el camino (el de los altavoces que enchufamos a la placa de la FPGA) la falta de linealidad del amplificador mezclará esas altas frecuencias hacia abajo y acabaremos oyéndolas.
El filtro recomendado por Temes consta de tres etapas:
- SCF = Switched Capacitor Filter. Se trata de un filtro discreto. Para evitar el ruido de conmutación del DAC (o sea, del pin de la FPGA en nuestro caso) este filtro muestrea la señal a mitad de cada bit y opera sobre ese valor estable.
- El siguiente paso es un búfer que elimina las transiciones suaves del SCF por tras más rápidas pero también más sencillas en frecuencia.
- Finalmente hay un filtro CT (Continuous Time) que es el RC de toda la vida.
O sea, que nuestras queridas placas FPGA se están saltando los pasos 1 y 2. Van directamente al 3. A lo mejor piensas: bueno, seguro que no hace falta tanta historia… Veamos que opina el mayor experto mundial en tecnología DAC/ADC Analog Devices. Por ejemplo el DAC de audio AD1853:
Vaya, resulta que sí tienen un interpolador para convertir la frecuencia de muestreo. Y además han preferido usar un modulador multibit en vez de uno de un solo bit como los de la FPGA…
Así que estas cosas sí son importantes. Si nos toca trabajar con una placa que sólo tenga el filtro RC, tendremos que aguantarnos con esa parte. Pero al menos, todo lo digital que va en la FPGA sí podemos hacerlo bien y mejorar así el sonido final. En la próxima entrada hablaremos sobre cómo escoger la frecuencia de sobremuestreo (OSR) y el diseño del interpolador.
¿Qué sistema FPGA comprar para retro informática?
Ya hemos discutido las ventajas de las FPGA para la retroinformática aquí. Pero si quieres empezar a probar estos sistemas, ¿cuál comprar? ¿Y dónde? En esta entrada voy a presentar los principales sistemas y compararlos.
MIST
Este es el sistema de referencia por la cantidad de máquinas que se han llevado a él. Por cierto, en la jerga de las FPGA para retro, a cada sistema portado lo denominan core. Para el MIST el core de referencia es el de Atari ST, pues es el que originó el proyecto. Sin embargo, están disponibles también cores para Amiga (incluido el Amiga 1200), los cuatro grandes ordenadores de 8 bits (Amstrad CPC, Spectrum, C64 y MSX) y varias consolas de 8 bits (Master System y NES). Hay varios otros cores de menor público disponibles.
El MIST tiene la ventaja de llevar bastante tiempo en desarrollo y estar por tanto bastante afinado. Se puede adquirir directamente de una tienda española (AmigaStore) a buen precio y con un plazo de entrega mínimo. Si 200€ os parece mucho dinero por un sistema así, es principalmente porque las FPGA son circuitos caros, sobre todo en tiradas pequeñas. MIST monta una FPGA bastante grande y eso influye en el precio.
Características destacables:
- Conexión a monitores VGA solo. Han de soportar refrescos menores de 60Hz para algunos cores. Conexión a TV usando un cable a medida.
- Ratón, teclado y mando de juegos todo USB.
- Compatible también con mandos antiguos (norma Atari).
- Puertos MIDI compatibles con hardware antiguo (disponible versión sin MIDI a menor precio)
- FPGA Altera Cyclone EP3C25
- 32 MByte de palabra de 16 bits
El tamaño de la FPGA es de 24k elementos lógicos, ~64kbytes de RAM embebida en bloques, ~1kbit de RAM embebida dispersa, 66 multiplicadores y 4 PLLs. ¿Esto qué significa? Pues que seguramente en esta FPGA cabe todo el sistema digital de una NeoGeo, por ejemplo. Sin embargo los videojuegos de NeoGeo de más de 256Mbits no cabrían en la memoria RAM. Aun no hay cores tan avanzados desarrollados. O sea, que MIST puede dar para mucho todavía.
ZX UNO
Este sistema ha nacido para el Spectrum y ofrece la experiencia más cercana a él que ningún otro puesto que permite hasta cargar los juegos por cinta (o audio del móvil). Es un sistema más económico que MIST, se puede adquirir por 65€ directamente a uno de los desarrolladores aquí. La razón del precio es que equipa una FPGA más económica pero suficiente para sistemas de 8 bits. No, no vamos a ver una NeoGeo aquí, pero sí toda la gama de ordenadores Sinclair recreada con fidelidad exacta.
Características:
- Conexión por video compuesto para televisores de tubo
- Conexión RGB para televisores modernas y monitores VGA usando cables a medida
- Teclado y ratón sólo PS/2
- Entrada de audio para leer cintas
- Conexión de mandos de norma Atari
- FPGA Xilinx Spartan XC6SLX9-2TQG144C
- 0.5 MByte de memoria
Esta es una buena opción también si queréis hacer el montaje de la placa vosotros mismos pues todos los diagramas de esquemático y PCB están disponibles de forma abierta. Si bien el conector de vídeo compuesto es el único estándar porque para la conexión a euroconector o VGA necesitarás hacerte un cable especial o comprarlo. Se rumorea que quizá Retrocables llegue a vender estos cables especiales.
Minimig
Este sistema es más antiguo que el ZX UNO y nació para el Amiga. Su core de Amiga está portado a MIST. Tiene la peculiaridad de llevar un procesador M68000 real, fuera de la FPGA. La FPGA se usa para implementar el resto de circuitos del Amiga. Existen cores de otros equipos también. Sus características son similares al MIST pero el precio es mayor, unos 290€. Se puede comprar también en AmigaStore.
Características:
- Conexión a VGA solo
- Puerto RS232, con lo que puede conectarse en serie a un PC
- Puertos para raton y teclados PS/2
- Puertos para raton y teclados Amiga
- FPGA Spartan 3 XC3S400 (400k puertas)
- 4MByte de memoria
Esta es una buena opción para los amantes de Amiga que quieren usar teclados y ratones originales. El poder conectarse en serie a ordenadores modernos puede ser interesante para transferencia de ficheros o juego en red. Aunque para transferir ficheros, grabar directamente en la tarjeta SD es mucho más rápido.
Otros sistemas
Hay otros sistemas que han tenido menor difusión que estos proyectos. En particular FPGA Arcade (se solía vender aquí por más de 300€). También es posible utilizar placas de desarrollo de FPGA, usadas para probar sistemas en general, con el fin de recrear sistemas retro pero esta opción no es buena para el aficionado porque no va a disponer de un entorno pensado para el retro, sino para el desarrollo de electrónica moderna.
Conclusión
Mi recomendación es adquirir un ZX-UNO si no nos queremos gastar mucho dinero y no esperamos usar sistemas de 16 bits. Y si queremos dar el salto a los 16 bits comprar un MIST. El Minimig lo dejo para los apasionados del Amiga.
Ordenadores que usaban el YM2151
Siguiendo con la lista de aparatos que usaban este chip, y tras repasar los juegos arcade aquí, paso a buscar ordenadores con este chip.
Sólo hay dos líneas de equipo que de serie vinieran con este chip. La primera es un equipo de 8 bits, el Sharp X1, que contaba con nuestro querido Z80. Además del repaso técnico de la Wikipedia, os recomiendo leer esta entrada del blog de SH2Central sobre este curioso equipo.
El otro equipo que usó este chip fue el famoso Sharp X68000. De nuevo SH2Central le da un repaso a este sistema que os recomiendo. Este sistema lleva un YM2151 pero en las fotografías de la placa base que he visto por internet no he podido encontrarlo. Quizá se encontraba en una placa hija o estaba integrado dentro de otro chip (me extrañaría). Os dejo una foto de la placa del misterio.
Juegos arcade que usaban el YM2151
¿Hasta qué punto podría resultar útil un clon del YM2151 en Verilog? Para responder a esa pregunta inicio una serie de tres entradas con datos exhaustivos de uso de este chip. Empezamos por los reyes de la casa: los videojuegos arcade.
El YM2151 fue ampliamente usado en los salones recreativos, sobre todo 1988 y 1998, la época del tandem M68000/Z80 en las placas arcade.
La siguiente lista está extraída a partir de los juegos emulados en MAME 173. En total 1012 juegos, sin contar clones ni versiones.
Año | Juego |
1980 | Battle Zone |
1980 | Defender |
1980 | Defense Command |
1980 | Mayday |
1980 | Tornado |
1980 | Zero |
1981 | Colony 7 |
1981 | Defence Command |
1981 | Stargate |
1981 | Star Trek |
1982 | Bubbles |
1982 | Jin |
1982 | Joust |
1982 | Robotron: 2084 |
1982 | Sinistar |
1982 | Splat! |
1983 | Blaster |
1983 | Mystic Marathon |
1983 | PlayBall! |
1984 | Atari System 1 BIOS |
1984 | Digital Controls Inc. license) |
1984 | Inferno |
1984 | Kung-Fu Master |
1984 | Lode Runner |
1984 | Lode Runner II – The Bungeling Strikes Back |
1984 | Marble Madness |
1984 | Paperboy |
1984 | Peter Pack-Rat |
1984 | Spartan X |
1984 | The Battle-Road |
1984 | Turkey Shoot |
1985 | Alien Arena |
1985 | Bubble System BIOS |
1985 | Galactic Warriors |
1985 | Gauntlet |
1985 | Gradius |
1985 | Hang-On |
1985 | Horizon |
1985 | Indiana Jones and the Temple of Doom |
1985 | Konami GT |
1985 | Konami RF2 – Red Fighter |
1985 | Lode Runner III – Majin No Fukkatsu |
1985 | Lode Runner III – The Golden Labyrinth |
1985 | Lot Lot |
1985 | Major League |
1985 | Nemesis |
1985 | Road Runner |
1985 | Space Harrier |
1985 | Speed Ball – Contest at Neonworld |
1985 | Spelunker |
1985 | TomCat |
1985 | TwinBee |
1986 | 720 Degrees |
1986 | Action Fighter |
1986 | Alex Kidd: The Lost Stars |
1986 | Body Slam |
1986 | Championship Sprint |
1986 | Dump Matsumoto |
1986 | Dunk Shot |
1986 | Enduro Racer |
1986 | Fantasy Zone |
1986 | Gauntlet II |
1986 | Genpei ToumaDen |
1986 | Grand Lizard |
1986 | High Speed |
1986 | Hopping Mappy |
1986 | Jackal |
1986 | Joust 2 – Survival of the Fittest |
1986 | Kaiketsu Yanchamaru |
1986 | Kid Niki – Radical Ninja |
1986 | Koi no Hotrock |
1986 | Lifeforce |
1986 | Lode Runner IV – Teikoku Karano Dasshutsu |
1986 | Out Run |
1986 | Panic Road |
1986 | Pin-Bot |
1986 | Quartet |
1986 | Quartet 2 |
1986 | Road Kings |
1986 | Rock’n Rage |
1986 | Rolling Thunder |
1986 | Salamander |
1986 | Side Arms – Hyper Dyne |
1986 | Sky Kid Deluxe |
1986 | Spelunker II |
1986 | Super Sprint |
1986 | The Lost Castle In Darkmist |
1986 | The Return of Ishtar |
1986 | Thunder Ceptor |
1986 | Thunder Ceptor II |
1986 | Tic-Tac-Strike |
1986 | Tokushu Butai Jackal |
1986 | Top Gunner |
1986 | WEC Le Mans 24 |
1986 | Youjyuden |
1987 | After Burner |
1987 | After Burner II |
1987 | Air Raid |
1987 | Ajax |
1987 | Alien Syndrome |
1987 | American Speedway |
1987 | APB – All Points Bulletin |
1987 | Arkanoid – Revenge of DOH |
1987 | Battle Chopper |
1987 | Big Guns |
1987 | Bionic Commando |
1987 | Bionic Commandos |
1987 | Black Panther |
1987 | Blazer |
1987 | Bullet |
1987 | City Bomber |
1987 | Contra |
1987 | Cross Shooter |
1987 | Dark Adventure |
1987 | Defense |
1987 | Devil World |
1987 | Double Dragon |
1987 | Dragon Spirit |
1987 | Dr. Toppel’s Adventure |
1987 | Dr. Toppel’s Tankentai |
1987 | Dunk Shot |
1987 | Extermination |
1987 | Exzisus |
1987 | F14 Tomcat |
1987 | Final Lap |
1987 | Fire! |
1987 | Flak Attack |
1987 | Full Throttle |
1987 | Galaga ’88 |
1987 | Gold Mine |
1987 | Gryzor |
1987 | Heavyweight Champ |
1987 | Hyper Crash |
1987 | Laser War |
1987 | Lifeforce |
1987 | Little Hero |
1987 | Lotto Fun |
1987 | Majuu no Ohkoku |
1987 | Midnight Landing |
1987 | Millionaire |
1987 | Mr. HELI no Daibouken |
1987 | Mustache Boy |
1987 | MX5000 |
1987 | Operation Bear |
1987 | Operation Wolf |
1987 | Pac-Mania |
1987 | Plump Pop |
1987 | Quester |
1987 | Quester Special Edition |
1987 | Rabbit Punch |
1987 | Rabio Lepus |
1987 | Rainbow Islands |
1987 | Rastan |
1987 | Rastan Saga |
1987 | Road Blasters |
1987 | Robotron: 2084 |
1987 | R-Type |
1987 | SDI – Strategic Defense Initiative |
1987 | Shadowland |
1987 | Shinobi |
1987 | Shuffle Inn |
1987 | Sonic Boom |
1987 | Street Fighter |
1987 | Sukeban Jansi Ryuko |
1987 | Super Hang-On |
1987 | Super League |
1987 | Thunder Blade |
1987 | Thundercade / Twin Formation |
1987 | Time Scanner |
1987 | Tokusyu Butai U.A.G. |
1987 | Top Dawg |
1987 | Top Secret |
1987 | Top Speed |
1987 | Typhoon |
1987 | Wonder Momo |
1987 | Yokai Douchuuki |
1988 | ’88 Games |
1988 | Ace Attacker |
1988 | Altered Beast |
1988 | Apache 3 |
1988 | Assault |
1988 | Assault Plus |
1988 | Asuka & Asuka |
1988 | Bakutotsu Kijuutei |
1988 | Banzai Run |
1988 | Beraboh Man |
1988 | Bonze Adventure |
1988 | Cabal |
1988 | Center Court |
1988 | Chequered Flag |
1988 | China Gate |
1988 | Chuka Taisen |
1988 | Crazy Cop |
1988 | Cyberball |
1988 | Cyclone |
1988 | Daimakaimura |
1988 | Devastators |
1988 | Double Dragon II – The Revenge |
1988 | Dynamite Dux |
1988 | Earthshaker |
1988 | Excite League |
1988 | Face Off |
1988 | Forgotten Worlds |
1988 | Gain Ground |
1988 | Galaxy Force 2 |
1988 | Gang Busters |
1988 | Garuka |
1988 | Ghouls’n Ghosts |
1988 | Gradius II – GOFER no Yabou |
1988 | Hard Drivin’ |
1988 | Hard Puncher |
1988 | Hot Chase |
1988 | Hot Rod |
1988 | Hyper Sports Special |
1988 | Iga Ninjyutsuden |
1988 | Image Fight |
1988 | Jigoku Meguri |
1988 | Jumping |
1988 | Juuouki |
1988 | Kabuki-Z |
1988 | Kageki |
1988 | Kickle Cubele |
1988 | Kick Off |
1988 | Kitten Kaboodle |
1988 | Konami ’88 |
1988 | Legend of Makai |
1988 | Lost Worlds |
1988 | Makai Densetsu |
1988 | Marchen Maze |
1988 | Meikyu Jima |
1988 | Metal Hawk |
1988 | Mirai Ninja |
1988 | Narc |
1988 | Ninja Gaiden |
1988 | Ninja Kazan |
1988 | Ninja Spirit |
1988 | Nyan Nyan Panic |
1988 | Ordyne |
1988 | P-47 – The Freedom Fighter |
1988 | P-47 – The Phantom Fighter |
1988 | Passing Shot |
1988 | Phelios |
1988 | Power Drift |
1988 | Rainbow Islands |
1988 | Ring no Ohja |
1988 | Saigo no Nindou |
1988 | Sai Yu Gou Ma Roku |
1988 | Scramble Spirits |
1988 | Secret Service |
1988 | Shadow Warriors |
1988 | Shingen Samurai-Fighter |
1988 | Space Station |
1988 | Splatter House |
1988 | Sukeban Jansi Ryuko |
1988 | Super Contra |
1988 | Superman |
1988 | Swords of Fury |
1988 | Takeda Shingen |
1988 | Taxi |
1988 | Tetris |
1988 | The Final Round |
1988 | The Main Event |
1988 | The NewZealand Story |
1988 | Thunder Cross |
1988 | Time Machine |
1988 | Torpedo Alley |
1988 | Turtle Ship |
1988 | Twin Eagle – Revenge Joe’s Brother |
1988 | U.S. Championship V’ball |
1988 | Vigilante |
1988 | Vindicators Part II |
1988 | Vulcan Venture |
1988 | Winning Run |
1988 | Wonder Boy III – Monster Lair |
1988 | World Court |
1988 | World Stadium |
1989 | Arbalester |
1989 | Area 88 |
1989 | Bad Cats |
1989 | Bad Lands |
1989 | Bay Route |
1989 | Big Run |
1989 | Bingo Circus |
1989 | Black Knight 2000 |
1989 | Blast Off |
1989 | Block Hole |
1989 | Block Out |
1989 | Buccaneers |
1989 | Burning Force |
1989 | Cabal |
1989 | Cadash |
1989 | Caliber 50 |
1989 | Crack Down |
1989 | Crime Fighters |
1989 | Cue Brick |
1989 | Cyberball 2072 |
1989 | Daisenpu |
1989 | Dangerous Seed |
1989 | Dirt Fox |
1989 | DownTown / Mokugeki |
1989 | Dragon Breed |
1989 | Dragon Unit / Castle of Dragon |
1989 | Dyger |
1989 | Dynamite Dux |
1989 | Dynasty Wars |
1989 | Earthshaker |
1989 | Elvira and the Party Monsters |
1989 | E-Swat – Cyber Police |
1989 | Exterminator |
1989 | Final Fight |
1989 | Finest Hour |
1989 | Flash Point |
1989 | Four Trax |
1989 | Galaxy Gunners |
1989 | Gigandes |
1989 | Golden Axe |
1989 | Gradius III |
1989 | Hachoo! |
1989 | Insector X |
1989 | Jitsuryoku!! Pro Yakyuu |
1989 | Jokerz! |
1989 | Jumbo Ozaki Super Masters Golf |
1989 | Jumping |
1989 | Kuhga – Operation Code ‘Vapor Trail’ |
1989 | Last Striker / Kyuukyoku no Striker |
1989 | Last Survivor |
1989 | Legend of Hero Tonma |
1989 | Line of Fire / Bakudan Yarou |
1989 | Mad Motor |
1989 | Marvel Land |
1989 | Master Ninja |
1989 | Match It |
1989 | Maze of Flott |
1989 | Meta Fox |
1989 | M.I.A. – Missing in Action |
1989 | Monday Night Football |
1989 | Mousin’ Around! |
1989 | MVP |
1989 | Ninja Ryukenden |
1989 | Playboy 35th Anniversary |
1989 | Plus Alpha |
1989 | Police Force |
1989 | Pool Sharks |
1989 | Quarth |
1989 | Racing Hero |
1989 | Robocop |
1989 | Rompers |
1989 | Round Up 5 – Super Delta Force |
1989 | R-Type II |
1989 | Saint Dragon |
1989 | Shadow Dancer |
1989 | Shisensho – Joshiryo-Hen |
1989 | Sichuan II |
1989 | Street Smart / Final Fight |
1989 | Strider |
1989 | Strider Hiryu |
1989 | S.T.U.N. Runner |
1989 | Super Masters Golf |
1989 | Super Monaco GP |
1989 | Super Volleyball |
1989 | Task Force Harrier |
1989 | Tecmo Knight |
1989 | Teenage Mutant Hero Turtles |
1989 | Teenage Mutant Ninja Turtles |
1989 | Tenchi wo Kurau |
1989 | The Astyanax |
1989 | The Lord of King |
1989 | Tough Turf |
1989 | Tournament Cyberball 2072 |
1989 | Transporter the Rescue |
1989 | Turbo Out Run |
1989 | Twin Falcons |
1989 | Twin Hawk |
1989 | U.N. Squadron |
1989 | U.S. Classic |
1989 | Valkyrie No Densetsu |
1989 | Vapor Trail – Hyper Offence Formation |
1989 | Whizz |
1989 | Wild Fang |
1989 | Wild Fang / Tecmo Knight |
1989 | Willow |
1989 | Winning Run Suzuka Grand Prix |
1989 | Wit’s |
1989 | World Stadium ’89 |
1989 | Wrestle War |
1989 | WWF Superstars |
1989 | X Multiply |
198? | Visco Roulette |
1990 | 1941: Counter Attack |
1990 | A.B. Cop |
1990 | Air Duel |
1990 | Aliens |
1990 | Alien Storm |
1990 | Atomic Point |
1990 | Aurail |
1990 | Back To the Future |
1990 | Back To The Future |
1990 | Bio-ship Paladin |
1990 | Bonanza Bros |
1990 | Boxy Boy |
1990 | Bugs Bunny Birthday Ball |
1990 | Carrier Air Wing |
1990 | Chiki Chiki Boys |
1990 | Chulgyeok D-Day |
1990 | Cisco Heat |
1990 | Crude Buster |
1990 | Daiku no Gensan |
1990 | Dark Seal |
1990 | D. D. Crew |
1990 | Diner |
1990 | Double Dragon 3 – The Rosetta Stone |
1990 | Dragon Saber |
1990 | Dr. Dude |
1990 | Final Crash |
1990 | Final Fight |
1990 | Final Lap 2 |
1990 | Gate of Doom |
1990 | G-LOC Air Battle |
1990 | G-LOC R360 |
1990 | Golly! Ghost! |
1990 | GP Rider |
1990 | Hammerin’ Harry |
1990 | Hard Drivin’ |
1990 | High Impact Football |
1990 | Jockey Club |
1990 | Kyuukai Douchuuki |
1990 | Lightning Fighters |
1990 | Magic Sword: Heroic Fantasy |
1990 | Major Title |
1990 | Mega Twins |
1990 | Mercs |
1990 | Michael Jackson’s Moonwalker |
1990 | Monky Elf |
1990 | Mug Smashers |
1990 | Nemo |
1990 | Over Drive |
1990 | Parodius DA! |
1990 | Phantasm |
1990 | Pistol Daimyo no Bouken |
1990 | Pool Sharks |
1990 | Pound for Pound |
1990 | Punk Shot |
1990 | Puzzle Club |
1990 | Race Drivin’ |
1990 | Race Drivin’ Panorama |
1990 | Radical! |
1990 | Riverboat Gambler |
1990 | Rod-Land |
1990 | Rollergames |
1990 | Rolling Thunder 2 |
1990 | Rough Racer |
1990 | R&T |
1990 | RyuKyu |
1990 | Senjou no Ookami II |
1990 | Smash T.V. |
1990 | Snapper |
1990 | Snow Bros. – Nick & Tom |
1990 | Souko Ban Deluxe |
1990 | Space Battle Ship Gomorrah |
1990 | Spinal Breakers |
1990 | Star Trax |
1990 | Steel Gunner |
1990 | Super Burger Time |
1990 | Surprise Attack |
1990 | Teenage Mutant Ninja Turtles |
1990 | The Bally Game Show |
1990 | The Cliffhanger – Edward Randy |
1990 | The Combatribes |
1990 | The Last Day |
1990 | The Phantom of the Opera |
1990 | The Simpsons |
1990 | The Winter Bobble |
1990 | Thunder & Lightning |
1990 | Trigon |
1990 | Trog |
1990 | Two Crude |
1990 | US AAF Mustang |
1990 | U.S. Navy |
1990 | Vandyke |
1990 | Whirlwind |
1990 | World Stadium ’90 |
1990 | Born To Fight |
1990 | Fantasy Land |
1990 | Wheels Runner |
1991 | 1991 Spikes |
1991 | 64th. Street – A Detective Story |
1991 | Acrobat Mission |
1991 | Agress – Missile Daisenryaku |
1991 | Atomic Punk |
1991 | Avenging Spirit |
1991 | Beauty Block |
1991 | Bells & Whistles |
1991 | Black Heart |
1991 | Blade Master |
1991 | Bomber Man |
1991 | Captain America and The Avengers |
1991 | Captain Commando |
1991 | Caveman Ninja |
1991 | China Town |
1991 | Cosmic Cop |
1991 | Cosmo Gang the Video |
1991 | Cotton |
1991 | Crime Fighters 2 |
1991 | Cross Blades! |
1991 | Cycle Warriors |
1991 | Desert Assault |
1991 | Detana!! Twin Bee |
1991 | Driver’s Eyes |
1991 | Dynablaster / Bomber Man |
1991 | Dynamic Country Club |
1991 | E.D.F. : Earth Defense Force |
1991 | Escape Kids |
1991 | F-15 Strike Eagle |
1991 | Gallop – Armed Police Unit |
1991 | Ghox |
1991 | Golfing Greats |
1991 | Grand Prix Star |
1991 | Gulf Storm |
1991 | Gunforce – Battle Fire Engulfed Terror Island |
1991 | Hacha Mecha Fighter |
1991 | Hasamu |
1991 | IQ Pipe |
1991 | Karate Blazers |
1991 | Ken-Go |
1991 | Knights of the Round |
1991 | Lemmings |
1991 | Lethal Thunder |
1991 | Lightning Swords |
1991 | Limited Edition Hang-On |
1991 | Lock On |
1991 | Magical Crystals |
1991 | Many Block |
1991 | Orius |
1991 | Pairs Love |
1991 | Pipi & Bibis / Whoopee!! |
1991 | Pollux |
1991 | Power Spikes |
1991 | Quiz Rouka Ni Tattenasai |
1991 | Quiz Syukudai wo Wasuremashita |
1991 | Raiga – Strato Fighter |
1991 | Rail Chase |
1991 | Rezon |
1991 | Riot City |
1991 | Robocop 2 |
1991 | Rohga Armor Force |
1991 | Rollergames |
1991 | Royal Ascot |
1991 | SD Gundam Psycho Salamander no Kyoui |
1991 | Solvalou |
1991 | Starblade |
1991 | Steel Gunner 2 |
1991 | Steel Talons |
1991 | Stoneage |
1991 | Street Fighter II: The World Warrior |
1991 | Strike Fighter |
1991 | Strike Force |
1991 | Strike Gunner S.T.G |
1991 | Sunset Riders |
1991 | Sunset Riders 2 |
1991 | Super High Impact |
1991 | Super Volley ’91 |
1991 | Super Volleyball |
1991 | Tank Force |
1991 | Tatakae Genshizin Joe & Mac |
1991 | Teenage Mutant Hero Turtles – Turtles in Time |
1991 | Teenage Mutant Ninja Turtles – Turtles in Time |
1991 | Teki Paki |
1991 | Terminator 2 – Judgment Day |
1991 | The Berlin Wall |
1991 | The King of Dragons |
1991 | The Simpsons |
1991 | Three Wonders |
1991 | Thunder Blaster |
1991 | Thunder Cross II |
1991 | Thunder Dragon |
1991 | Thunder Strike |
1991 | Thunder Zone |
1991 | Toushin Blazers |
1991 | Tumble Pop |
1991 | Turbo Force |
1991 | Ultraman |
1991 | Vendetta |
1991 | Winning Run ’91 |
1991 | Wolf Fang -Kuhga 2001- |
1991 | Wonder 3 |
1991 | WWF WrestleFest |
1991 | Xexex |
1992 | Adventure Quiz Capcom World 2 |
1992 | Aero Fighters |
1992 | Air Combat |
1992 | Arm Champs II v1.7 |
1992 | Arm Champs II v2.6 |
1992 | Asterix |
1992 | Bakuretsu Breaker |
1992 | Balloon Brothers |
1992 | Battle of the Solar System |
1992 | Big Fight – Big Trouble In The Atlantic Ocean |
1992 | Big Striker |
1992 | Blandia |
1992 | Blaze On |
1992 | Block Carnival / Thunder & Lightning 2 |
1992 | Bomber Lord |
1992 | Bomber Man World |
1992 | Bomber Man World / New Dyna Blaster – Global Quest |
1992 | Boogie Wings |
1992 | B.Rap Boys |
1992 | B.Rap Boys Special |
1992 | Bubble Trouble |
1992 | Bucky O’Hare |
1992 | Cactus |
1992 | Dangerous Dungeons |
1992 | Dark Seal 2 |
1992 | Dark Tower |
1992 | D-Con |
1992 | Death Brade |
1992 | Diet Go Go |
1992 | Dogyuun |
1992 | Dragon Bowl |
1992 | Explosive Breaker |
1992 | Final Lap 3 |
1992 | Final Star Force |
1992 | FixEight |
1992 | Flying Tiger |
1992 | Fujiyama Buster |
1992 | Funky Jet |
1992 | Galmedes |
1992 | Grind Stormer |
1992 | Gun Ball |
1992 | Heated Barrel |
1992 | Hook |
1992 | Jumping Pop |
1992 | Kageki |
1992 | Koutetsu Yousai Strahl |
1992 | Legionnaire |
1992 | Lucky & Wild |
1992 | Mahou Keibitai Gun Hohki |
1992 | Major Title 2 |
1992 | Mortal Kombat |
1992 | Mutant Fighter |
1992 | Mystic Riders |
1992 | New Atomic Punk – Global Quest |
1992 | Nitro Ball |
1992 | Olympic Soccer ’92 |
1992 | Pang Pom’s |
1992 | Peter Pan |
1992 | Quiz & Dragons: Capcom Quiz Game |
1992 | Quiz F1 1-2 Finish |
1992 | Quiz Kokology |
1992 | Quiz Mekurumeku Story |
1992 | Rezon |
1992 | Riot |
1992 | R-Type Leo |
1992 | Saboten Bombers |
1992 | Sangokushi II |
1992 | SD Gundam Neo Battling |
1992 | Seibu Cup Soccer |
1992 | Seibu Cup Soccer :Selection: |
1992 | Shogun Warriors |
1992 | Sky Alert |
1992 | Soldam |
1992 | Sonic Wings |
1992 | S.S. Mission |
1992 | Street Fighter II’: Champion Edition |
1992 | Street Fighter II’: Hyper Fighting |
1992 | Street Fighter II’: Magic Delta Turbo |
1992 | Street Fighter II: The World Warrior |
1992 | Street Fighter II’ Turbo: Hyper Fighting |
1992 | Super Hang-On |
1992 | Super Spacefortress Macross / Chou-Jikuu Yousai Macross |
1992 | Super World Stadium |
1992 | Super World Stadium ’92 |
1992 | Super World Stadium ’92 Gekitouban |
1992 | Suzuka 8 Hours |
1992 | Tank Battle |
1992 | Tenchi wo Kurau II: Sekiheki no Tatakai |
1992 | The Great Ragtime Show |
1992 | The Irem Skins Game |
1992 | The Karate Tournament |
1992 | Tokoro San no MahMahjan |
1992 | Total Carnage |
1992 | Truxton II / Tatsujin Oh |
1992 | Ultraman Club – Tatakae! Ultraman Kyoudai!! |
1992 | Undercover Cops |
1992 | Undercover Cops – Alpha Renewal Version |
1992 | Varth: Operation Thunderstorm |
1992 | Warriors of Fate |
1992 | Wild Pilot |
1992 | Wild West C.O.W.-Boys of Moo Mesa |
1992 | Wizard Fire |
1992 | X-Men |
1992 | Zing Zing Zip |
1993 | Air Assault |
1993 | Athena no Hatena ? |
1993 | Atom |
1993 | Batsugun |
1993 | Batsugun – Special Version |
1993 | Biaofeng Zhanjing |
1993 | Big Bang |
1993 | Blue Hawk |
1993 | Bombjack Twin |
1993 | Cadillacs and Dinosaurs |
1993 | Cadillacs: Kyouryuu Shin Seiki |
1993 | Captain Flag |
1993 | Chimera Beast |
1993 | Cybattler |
1993 | Cyber Sled |
1993 | Daioh |
1993 | Denjin Makai |
1993 | Dinosaur Hunter |
1993 | Double Wings |
1993 | Dragonball Z |
1993 | Dragon Gun |
1993 | F-1 Grand Prix Star II |
1993 | Fighter’s History |
1993 | Final Tetris |
1993 | Fire Barrel |
1993 | Godzilla |
1993 | GunNail |
1993 | Gussun Oyoyo |
1993 | Hard Drivin’s Airborne |
1993 | Hayaoshi Quiz Ouza Ketteisen – The King Of Quiz |
1993 | Hyper Duel |
1993 | International Toote II |
1993 | In The Hunt |
1993 | J. J. Squawkers |
1993 | Jump Kids |
1993 | Kaitei Daisensou |
1993 | Kero Kero Keroppi no Issyoni Asobou |
1993 | Knuckle Bash |
1993 | Lady Killer |
1993 | Mad Shark |
1993 | Mahou Daisakusen |
1993 | Masked Riders Club Battle Race |
1993 | Match It II |
1993 | Mobile Suit Gundam |
1993 | Moeyo Gonta!! |
1993 | Muscle Bomber Duo: Heat Up Warriors |
1993 | Muscle Bomber Duo: Ultimate Team Battle |
1993 | Muscle Bomber: The Body Explosion |
1993 | Ninja Baseball Bat Man |
1993 | Ninja Baseball Bat Man II |
1993 | Oishii Puzzle Ha Irimasenka |
1993 | Peek-a-Boo! |
1993 | Perfect Soldiers |
1993 | Poitto! |
1993 | Premier Soccer |
1993 | Quiz Gakumon no Susume |
1993 | Quiz Kokology 2 |
1993 | Raiden II |
1993 | Risky Challenge |
1993 | Sadari |
1993 | Saturday Night Slam Masters |
1993 | Schmeiser Robo |
1993 | SD Gundam Sangokushi Rainbow Tairiku Senki |
1993 | Shadow Force |
1993 | Shisensho II |
1993 | Sorcer Striker |
1993 | Street Drivin’ |
1993 | Superior Soldiers |
1993 | Super Spacefortress Macross II / Chou-Jikuu Yousai Macross II |
1993 | Super World Stadium ’93 |
1993 | Suzuka 8 Hours 2 |
1993 | The Punisher |
1993 | Thunder Dragon 2 |
1993 | Toffy |
1993 | Triple Fun |
1993 | Ultra Toukon Densetsu |
1993 | U.N. Defense Force: Earth Joker |
1993 | V-Five |
1993 | War of Aero – Project MEIOU |
1993 | Wing Force |
1993 | Yakyuu Kakutou League-Man |
1993 | Zero Team |
1993 | Zero Team Selection |
1993 | Zero Team Suicide Revival Kit |
1993 | Zero Team USA |
1994 | 1000 Miglia: Great 1000 Miles Rally |
1994 | Arcadia |
1994 | B.C. Kid / Bonk’s Adventure / Kyukyoku!! PC Genjin |
1994 | Best Of Best |
1994 | Blazing Tornado |
1994 | Blood Warrior |
1994 | Dharma Doujou |
1994 | Dragonball Z 2 – Super Battle |
1994 | Dream Soccer ’94 |
1994 | Eight Forces |
1994 | Geo Storm |
1994 | Gouketsuji Ichizoku 2 |
1994 | Great 1000 Miles Rally: Evolution Model!!! |
1994 | Great 1000 Miles Rally: U.S.A Version! |
1994 | Gun Dealer ’94 |
1994 | Gun Force II |
1994 | Gun Hard |
1994 | Gun Master |
1994 | Kick for the Goal |
1994 | Kingdom Grandprix |
1994 | Kokontouzai Eto Monogatari |
1994 | Krazy Bowl |
1994 | Last Fortress – Toride |
1994 | Locked ‘n Loaded |
1994 | Magical Error wo Sagase |
1994 | Magical Speed |
1994 | Magicball Fighting |
1994 | Mazinger Z |
1994 | Metal Saver |
1994 | Night Slashers |
1994 | Oedo Fight |
1994 | Orbs |
1994 | Pack’n Bang Bang |
1994 | Pang Pang |
1994 | Pnickies |
1994 | Pokonyan |
1994 | Power Instinct 2 |
1994 | Power Kick |
1994 | Primella |
1994 | Pro Mahjong Kiwame |
1994 | PuzzLove |
1994 | Quiz & Dragons: Capcom Quiz Game |
1994 | Quiz Ghost Hunter |
1994 | Raiden DX |
1994 | Rapid Hero |
1994 | Scud Hammer |
1994 | Shippu Mahou Daisakusen |
1994 | Snow Bros. 2 – With New Elves / Otenki Paradise |
1994 | SunA Quiz 6000 Academy |
1994 | Super Bar |
1994 | Super Toffy |
1994 | Super Trio |
1994 | Super-X |
1994 | Tattoo Assassins |
1994 | Tickee Tickats |
1994 | Tokoro San no MahMahjan 2 |
1994 | Toride II |
1994 | Toride II Adauchi Gaiden |
1994 | Toride II Bok Su Oi Jeon Adauchi Gaiden |
1994 | Toryumon |
1994 | Wiggie Waggie |
1995 | Choky! Choky! |
1995 | Cookie & Bibi |
1995 | Daitoride |
1995 | Dolmen |
1995 | DonPachi |
1995 | Extreme Downhill |
1995 | Ganbare Ginkun |
1995 | Gogetsuji Legends |
1995 | Gouketsuji Gaiden – Saikyou Densetsu |
1995 | Great 1000 Miles Rally 2 USA |
1995 | Gundhara |
1995 | Hatch Catch |
1995 | Honey Dolls |
1995 | Hyper Pacman |
1995 | Kero Kero Keroppi’s Let’s Play Together |
1995 | Ltd. |
1995 | Mahjong Doukyuusei |
1995 | Mahjong Doukyuusei Special |
1995 | Mega Man: The Power Battle |
1995 | Metamoqester |
1995 | Mille Miglia 2: Great 1000 Miles Rally |
1995 | Mouse Shooter GoGo |
1995 | Nouryoku Koujou Iinkai |
1995 | Oni – The Ninja Master |
1995 | Othello Derby |
1995 | Pang! 3 |
1995 | Pang! 3: Kaitou Tachi no Karei na Gogo |
1995 | Pretty Soldier Sailor Moon |
1995 | Pururun |
1995 | Puzzli |
1995 | Quiz Tonosama no Yabou 2: Zenkoku-ban |
1995 | Rockman: The Power Battle |
1995 | R-Shark |
1995 | Silver Millennium |
1995 | Sokonuke Taisen Game |
1995 | Sotsugyo Shousho |
1995 | Twin Action |
1995 | Twin Adventure |
1995 | Varia Metal |
1995 | Back To the Future |
1995 | Yori Jori Kuk Kuk | 1995 | Wonder League Star – Sok-Magicball Fighting |
1995 | World PK Soccer |
1995 | X Se Dae Quiz |
1995 | Zombie Raid |
1996 | 1945 Part-2 |
1996 | Air Attack |
1996 | Air Gallet |
1996 | Akuu Gallet |
1996 | Aquarium |
1996 | Back Street Soccer |
1996 | Bal Cube |
1996 | Bang Bang Ball |
1996 | Battle Garegga |
1996 | Battle Garegga – New Version |
1996 | Battle Garegga – Type 2 |
1996 | Carket Ball |
1996 | Come Back Toto |
1996 | Cookie & Bibi 2 |
1996 | Crazy Fight |
1996 | Daitoride |
1996 | Fancy World – Earth of Crisis |
1996 | Ghost Hunter |
1996 | Grand Striker 2 |
1996 | Hotdog Storm |
1996 | Lei Shen Zhuan Thunder Deity Biography |
1996 | Ltd. |
1996 | Mouja |
1996 | Mouse Attack |
1996 | Multi Game ’96 |
1996 | Pac-Slot |
1996 | Pop Bingo |
1996 | Raiden II New / Raiden DX |
1996 | Sankokushi |
1996 | SD Fighters |
1996 | Toppy & Rappy |
1996 | Tut’s Tomb |
1996 | Ultra Balloon |
1996 | Wonder League ’96 |
1997 | B.C. Story |
1997 | Beach Festival World Championship 1997 |
1997 | Burglar X |
1997 | Cookie & Bibi 3 |
1997 | DoDonPachi |
1997 | Got-cha Mini Game Festival |
1997 | Mahjong Gakuensai |
1997 | MuHanSeungBu |
1997 | New Zero Team |
1997 | Pasha Pasha Champ Mini Game Festival |
1997 | Puzzle Break |
1997 | Red Hawk |
1997 | R-Type II |
1997 | Su Ho Seong |
1997 | Twinkle |
1998 | Armed Police Batrider |
1998 | Bubble 2000 |
1998 | Dangun Feveron |
1998 | Date Quiz Go Go |
1998 | ESP Ra.De. |
1998 | Fever SOS |
1998 | Guardian Storm |
1998 | Hot Bubble |
1998 | International Toote |
1998 | Jeon Sin – Guardian Storm |
1998 | Mahjong Gakuensai 2 |
1998 | New HyperMan |
1998 | Puzzle Uo Poko |
1998 | Rapid Fire v1.0 |
1998 | Rapid Fire v1.1 |
1998 | Real Battle Mahjong King |
1998 | Red Fox War Planes II |
1998 | Sen Jing – Guardian Storm |
1998 | Snow Bros. 2 – With New Elves / Otenki Paradise |
1998 | Stagger I |
1998 | Zero Point |
1999 | Battle Bakraid |
1999 | Battle Bakraid – Unlimited Version |
1999 | Battle Bubble |
1999 | Cool Minigame Collection |
1999 | Crusher Makochan |
1999 | Gaia Crusaders |
1999 | Guwange |
1999 | Huo Feng Huang |
1999 | Jumping Break |
1999 | Knuckle Bash 2 |
1999 | Koro Koro Quest |
1999 | Lup Lup Puzzle / Zhuan Zhuan Puzzle |
1999 | Ma Cheon Ru |
1999 | Mallet Madness v2.1 |
1999 | More More |
1999 | More More Plus |
1999 | Mosaic |
1999 | Pop’s Pop’s |
1999 | Puzzle Bang Bang |
1999 | Royal Poker 2 |
1999 | Super Lup Lup Puzzle / Zhuan Zhuan Puzzle |
1999 | The Legend of Silkroad |
1999 | Tobikose! Jumpman |
1999 | Vamf x1/2 |
1999 | Vamp x1/2 |
1999 | Warriors of Fate |
1999 | Zero Point 2 | 2000 | Date Quiz Go Go Episode 2 |
2000 | Ganbare! Marine Kun |
2000 | Mang-Chi |
2000 | Mission Craft |
2000 | Mr. Dig |
2000 | Puzzlet |
2000 | Spectrum 2000 |
2000 | Zero Team 2000 |
2001 | Age Of Heroes – Silkroad 2 |
2001 | Boong-Ga Boong-Ga |
2001 | Diet Family |
2001 | Final Godori |
2001 | Fire Hawk |
2001 | Mr. Kicker |
2001 | Thunder Heroes |
2001 | Toy Land Adventure |
2001 | Wivern Wings |
2001 | Wyvern Wings |
2002 | Puzzle King |
2002 | Snow Brothers 3 – Magical Adventure |
2003 | Agress – Missile Daisenryaku |
2003 | Ball Boy |
2006 | ISG Selection Master Type 2006 BIOS |
2006 | Tetris / Bloxeed |
2008 | Fantasy Zone |
2008 | Fantasy Zone II – The Tears of Opa-Opa |
2008 | Shinobi / FZ-2006 |
2009 | R-Type |
2012 | DoDonPachi |
2012 | Robotron: 2084 |
2013 | Out Run |
2014 | Out Run |
2015 | Robotron: 2084 |
Generador de ruido del YM2151
El ruido que oímos en los juegos, normalmente usado para simular explosiones, golpes, etc. es generado de forma aleatoria en el interior del chip. ¿Aleatoria de verdad? Bueno, aunque los procesadores modernos sí suelen llevar un verdadero generador de números aleatorios basado en propiedades físicas de los circuitos, en el pasado y en muchas aplicaciones modernas se usa un tipo de circuito llamado registro de desplazamiento con realimentación lineal, LFSR por sus siglas en inglés (wikipedia).
En el código fuente del emulador del MAME (ym2151.c) encontramos la siguiente tabla para emular el ruido:
/*
Noise LFO waveform.
Here are just 256 samples out of much longer data.
It does NOT repeat every 256 samples on real chip and I wasnt able to find
the point where it repeats (even in strings as long as 131072 samples).
I only put it here because its better than nothing and perhaps
someone might be able to figure out the real algorithm.
Note that (due to the way the LFO output is calculated) it is quite
possible that two values: 0x80 and 0x00 might be wrong in this table.
To be exact:
some 0x80 could be 0x81 as well as some 0x00 could be 0x01.
*/
static UINT8 lfo_noise_waveform[256] = {
0xFF,0xEE,0xD3,0x80,0x58,0xDA,0x7F,0x94,0x9E,0xE3,0xFA,0x00,0x4D,0xFA,0xFF,0x6A,
0x7A,0xDE,0x49,0xF6,0x00,0x33,0xBB,0x63,0x91,0x60,0x51,0xFF,0x00,0xD8,0x7F,0xDE,
0xDC,0x73,0x21,0x85,0xB2,0x9C,0x5D,0x24,0xCD,0x91,0x9E,0x76,0x7F,0x20,0xFB,0xF3,
0x00,0xA6,0x3E,0x42,0x27,0x69,0xAE,0x33,0x45,0x44,0x11,0x41,0x72,0x73,0xDF,0xA2,
0x32,0xBD,0x7E,0xA8,0x13,0xEB,0xD3,0x15,0xDD,0xFB,0xC9,0x9D,0x61,0x2F,0xBE,0x9D,
0x23,0x65,0x51,0x6A,0x84,0xF9,0xC9,0xD7,0x23,0xBF,0x65,0x19,0xDC,0x03,0xF3,0x24,
0x33,0xB6,0x1E,0x57,0x5C,0xAC,0x25,0x89,0x4D,0xC5,0x9C,0x99,0x15,0x07,0xCF,0xBA,
0xC5,0x9B,0x15,0x4D,0x8D,0x2A,0x1E,0x1F,0xEA,0x2B,0x2F,0x64,0xA9,0x50,0x3D,0xAB,
0x50,0x77,0xE9,0xC0,0xAC,0x6D,0x3F,0xCA,0xCF,0x71,0x7D,0x80,0xA6,0xFD,0xFF,0xB5,
0xBD,0x6F,0x24,0x7B,0x00,0x99,0x5D,0xB1,0x48,0xB0,0x28,0x7F,0x80,0xEC,0xBF,0x6F,
0x6E,0x39,0x90,0x42,0xD9,0x4E,0x2E,0x12,0x66,0xC8,0xCF,0x3B,0x3F,0x10,0x7D,0x79,
0x00,0xD3,0x1F,0x21,0x93,0x34,0xD7,0x19,0x22,0xA2,0x08,0x20,0xB9,0xB9,0xEF,0x51,
0x99,0xDE,0xBF,0xD4,0x09,0x75,0xE9,0x8A,0xEE,0xFD,0xE4,0x4E,0x30,0x17,0xDF,0xCE,
0x11,0xB2,0x28,0x35,0xC2,0x7C,0x64,0xEB,0x91,0x5F,0x32,0x0C,0x6E,0x00,0xF9,0x92,
0x19,0xDB,0x8F,0xAB,0xAE,0xD6,0x12,0xC4,0x26,0x62,0xCE,0xCC,0x0A,0x03,0xE7,0xDD,
0xE2,0x4D,0x8A,0xA6,0x46,0x95,0x0F,0x8F,0xF5,0x15,0x97,0x32,0xD4,0x28,0x1E,0x55
};
Jarek Burczynski, el autor del emulador del YM2151 usado en MAME y casi en cualquier otro sitio, habla sobre cómo estas medidas de la salida del YM2151 no son periódicas, incluso después de más de cien mil muestras. También dice que algunos valores podrían estar mal debido a la forma de extraer los datos y su relación con el oscilador de baja frecuencia del chip (el LFO).
Asumiendo que estos valores debían de provenir de un LFSR y que lo más lógico era tener un LFSR por cada bit, apliqué el algoritmo de Berlekamp-Massey (wikipedia) para obtener ese supuesto registro de desplazamiento. Y este fue el resultado:
Para todos los bits, salvo el 0 y el 4, de la secuencia de Jarek B. existe un LFSR de orden 19 y realimentación en las etapas 0, 1, 14, 15, 17 y 18.
Así que los bits que no se extrajeron bien en algunos casos fueron el 0 y el 4 y no el 0 y el 8 como pensaba Jarek. Fijaos que es la misma secuencia pseudoaleatoria para todos los bits de la palabra de ruido pero como cada LFSR está iniciado en un punto distinto de la secuencia, no van a coincidir nunca. La secuencia completa de cada bit tiene una longitud de 2^18, mucho mayor que los cien mil valores que Jarek tomó del chip. Además para ver una repetición tiene que coincidir que todas las secuencias se estén repitiendo. No voy a hacer el cálculo, pero el periodo de la secuencia es mucho mayor que 2^18.
Con estos datos ya es posible usar el mismo circuito que el original para producir el mismo ruido. Esto se puede aplicar a corregir el fichero ym2151.c de MAME o a seguir escribiendo el clón en verilog, que es lo que me ocupa a mí.
En la próxima entrada escribiré los valores con los que hay que iniciar cada LFSR para obtener la secuencia de ruido.
Primera nota musical con el YM2151
Después de prepararme para controlar un YM2151 a través de MAME (explicación). Aquí va mi primera nota, no sin esfuerzo. Para ello escribo los siguientes valores en los registros:
Registro | Nombre | Valor | Explicación |
---|---|---|---|
Del $60 al $7F | Total Level | $00 | volumen |
$20 | Connection | $C7 | $C = Salida por izquierda y derecha $7 = conexión tipo 7 |
$28 | Key Code | $4A | $4 = octava $A = nota (la) |
$40 | Phase Multiplier | 1 | |
$C0 | Detune 2 | 0 | |
$38 | Phase Modulation Sensitivity | 0 | |
Del $80 al $83 | Attack Rate | $10 | Comienzo de la envolvente |
Del $A0 al $A3 | Decay 1 Rate | $10 | Caída de la envolvente |
Del $C0 al $C3 | Decay 2 Rate | $10 | Caída de la envolvente |
Del $E0 al $E3 | Release Rate | $8 | Caída de la envolvente |
$78 | Key On | $78 | Comienza la envolvente para todos los operadores del canal 0 |
Sólo con esto ya se consigue sonido… una vez. Para repetirlo hay que volver a escribir a YM_KEYON ($78), esta vez con un $00 y luego volver a escribir un $78 para que empiece el sonido de nuevo. La repetición la hago en el código usando los temporizadores del YM2151 para esperar aproximadamente medio segundo.
A continuación está el código completo en ensamblador del 6809. Este código lo ensamblo y corro con el MAME.
; YM Registers
YM_KEYON EQU $08
YM_TIMERB EQU $12
YM_TIMER_CTRL EQU $14
YM_CT EQU $1B
YM_CONNECTION EQU $20
YM_KEY_CODE EQU $28
YM_KEY_FRACTION EQU $30
YM_PMS EQU $38
YM_PHASE_MUL EQU $40
YM_DETUNE2 EQU $C0
YM_ATTACK_RATE EQU $80
YM_DECAY1_RATE EQU $A0
YM_DECAY2_RATE EQU $C0
YM_RELEASE_RATE EQU $E0
; YM LOCATION IN THE MEMORY MAP
YM_ADR EQU $2000
YM_DATA EQU $2001
ORG $8000
RESET LDD #$6800
TFR D,S
; SET TOTAL LEVEL TO 00 FOR ALL CHANNELS
LDA #$60
STA $6000
TL_NXT: LDA $6000
CMPA #$80
BEQ PLAY
LDB #$00
JSR WRITE_YM
INC $6000
BRA TL_NXT
PLAY JSR WAIT
LDB #$C7
LDA #YM_CONNECTION
JSR WRITE_YM
LDB #$4A ; A 440Hz
LDA #YM_KEY_CODE
JSR WRITE_YM
LDB #1
LDA #YM_PHASE_MUL
JSR WRITE_YM
CLRB
LDA #YM_DETUNE2
JSR WRITE_YM
CLRB
LDA #YM_PMS
JSR WRITE_YM
; Envelope
CLRA
EG58 STA $6000
LDA #YM_ATTACK_RATE
ADDA $6000
LDB #$10
JSR WRITE_YM
LDA #YM_DECAY1_RATE
ADDA $6000
LDB #$10
JSR WRITE_YM
LDA #YM_DECAY2_RATE
ADDA $6000
LDB #$10
JSR WRITE_YM
LDA #YM_RELEASE_RATE
ADDA $6000
LDB #$8
JSR WRITE_YM
LDA $6000
INCA
CMPA #4
BNE EG58
KEYON:
LDB #$78
LDA #YM_KEYON
JSR WRITE_YM
; Wait for 0.5s before starting again
LDA #7
STA $6000
L59 LDA #YM_TIMERB
LDB 0
JSR WRITE_YM
LDA #YM_TIMER_CTRL
LDB #$2A
JSR WRITE_YM
L60 LDA YM_DATA
ANDA #2
BEQ L60
LDA #YM_TIMER_CTRL
LDB #$30 ; Reset flags
JSR WRITE_YM
DEC $6000
BNE L59
; key off
LDB #$00
LDA #YM_KEYON
JSR WRITE_YM
LBRA PLAY ; play it again, Sam
WAIT LDA #$FF
LOOP DECA
BNE LOOP
RTS
WRITE_YM:
JSR WAIT_YM
STA YM_ADR
JSR WAIT_YM
STB YM_DATA
RTS
WAIT_YM:
PSHS A ;
LDA YM_DATA
ANDA #$80
BNE WAIT_YM
PULS A ;
RTS
IRQ_SER RTI
TopMem EQU $FFF8
FILL $FF,TopMem-*
FDB IRQ_SER ; $FFF8
FDB $FFFF, $FFFF
FDB RESET
Sacar sonido del YM2151 en MAME
Después de más de un año de parada retomo la labor de clonar el YM2151 en FPGA. Los chips FM de Yamaha siguen sin estar disponibles en Verilog/VHDL y son una parte crucial si algún día queremos ver equipos de 16 bits (Megadrive, X68000, CPS1, SEGA System 16, etc.) recreados en FPGA y librarnos de los problemas de temporización e inexactitudes de la emulación.
El problema del YM2151 es su pésima documentación. No sólo porque el documento que circula escaneado por internet esté borroso y contenga partes ilegibles, sino porque en sí era un mal documento. El mapa de registros no está bien explicado y no hay ni un puñetero ejemplo de cómo generar sonidos. Esto en Japón, con los ingenieros de Yamaha al lado no sería gran problema. O quizá en su momento había herramientas de generación de sonidos que facilitaban la labor de programación de estos chips. Pero hoy en día, con sólo la documentación es imposible aclararse.
Jarek Burczynski además de lograr escribir su propio apellido, escribió el emulador de YM2151 usado en MAME. Cuenta en los créditos (en el ym2151.h) que contó con la colaboración de Shigeharu Isoda, un ingeniero de sonido de SEGA que conocía bien el chip. Shigeharu le pasó la documentación en japonés (ficheros que no han visto la luz de internet, por cierto) y sobre todo contestó a muchas preguntas. Algo fundamental si esa documentación en japonés es tan pobre como la que existe en inglés. También contó con la ayuda de otros con acceso a un chip real, quienes le tomaron medidas.
Pues bien, dada la escasez de documentación útil del YM2151, el emulador de Jarek B. va a ser una pieza fundamental para desentrañar este chip. Primero trataré de hacer funcionar las cosas en el emulador y luego de replicarlas en el chip real. Compararé los resultados y, por supuesto, trataré de replicar el chip real en Verilog, no el emulador.
Podría coger los ficheros ym2151.c, ym2151.h de MAME, adaptarlos a mi propio programa en C y explorarlos así. Sin embargo, prefiero un mecanismo más fiel a la época. He tomado como referencia el juego Gryzor. De él, la ROM 633e01.12a contiene el código del procesador 6809 que dirigía el sonido. El procesador principal escribía el código del sonido en un registro al que tenía acceso también este coprocesador. Según el código, este 6809 mandaba instrucciones al YM2151 para reproducir la melodía o el efecto sonoro adecuado.
MAME permite ejecutar un juego con ROMs alternativas. Lo que he hecho es ensamblar mi propia versión de la ROM de sonido de Gryzor, donde ejecuto mi propio código, y correrla con MAME. De esta forma puedo escuchar la salida de sonido rápidamente. MAME advierte de que la ROM no contiene lo esperado pero reproduce el juego bien.
En la siguiente entrada explicaré cómo conseguí el primer sonido del YM2151 usando este método.
Sistemas retro en FPGA ¿Por qué?
Con todo el entusiasmo generado por el ZX Uno, un proyecto español originado en el foro Zona de pruebas, que recrea un ZX Spectrum (entre otros) en una pequeña placa con una FPGA, muchos se están preguntando… ¿qué es una FPGA? ¿Por qué es mejor que emular?
Hay un vídeo en youtube que trata de explicar esto en relación a otro gran proyecto abierto de recreación en FPGA, el Mist. Sin embargo, creo que la explicación no satisfará a muchos con ansias de entender mejor la ventaja. Así que me he animado a escribir esta entrada.
Supongo que sabes que un ordenador, clásico o no, se compone de básicamente de estos elementos:
- Procesador (CPU)
- Memoria
- Sistema de E/S (Entrada/Salida), incluye teclado, vídeo, sonido, cinta, disco…
En la imagen tenemos la placa del ZX Spectrum con estos componentes marcados. Hay memoria que contiene el sistema (el BASIC en un ordenador de 8 bits). A esta memoria la llamamos ROM, porque no puede borrarse. Hay otra memoria que se usa para guardar los datos con los que el procesador trabaja, que llamamos RAM. Por supuesto está la CPU y un chip bastante grande marcado como FERRANTI ULA que contiene los sistemas de entrada y salida. A su lado hay dos piezas metálicas que contienen cuarzo y se usan para generar el reloj del sistema. El número 4.4336 que puede leerse es la frecuencia en MHz para la que está diseñado ese cristal, usado en el circuito de vídeo.
Un emulador es un programa que recrea la función de todos estos elementos: uno a uno y dentro de las restricciones temporales, de sonido e imagen que plantea el sistema sobre el que corre el emulador. Sin embargo, en el equipo real estos chips funcionan todos a la vez. Es más, en su interior hay miles de componentes que también funcionan a la vez. El emulador trata de recrear lo que el programa original está haciendo. Si el programa original decía: coge dos números de memoria y súmalos. El emulador hará eso. Pero… la placa original no hacía exactamente eso.
Bueno, sumaba los dos números pero pasaban más cosas. Esos números eran transportados hasta el interior de la CPU. Almacenados en una memoria especial llamado «registro» del procesador y pasados a través de otra etapa dentro del procesador encargada de hacer sumas. Cada uno de estos elementos estaba fabricado con transistores y cada uno de estos transistores tenía su propia actividad que ocurría al ritmo marcado por el reloj: 3,5MHz en un Spectrum. Y mientras tanto el chip de vídeo seguía con su actividad, y el altavoz seguía funcionando y la cinta moviéndose… Todo ocurría a la vez (en paralelo).
En el emulador, todo ocurre en serie: paso a paso. El emulador simula qué hace la CPU durante un tiempo. Se para y mira qué hace el chip de vídeo. Se para y atiende al sonido. Vuelve la mirada hacia el teclado… Así que las cosas no pasan a la vez y normalmente esto no se nota. Los ratitos que el emulador dedica a cada tarea son lo suficientemente cortos como para que no se note… Casi nunca. Cuando un programa necesita, por diseño o por casualidad, una relación de tiempo más precisa entre los componentes pasamos a necesitar equipos mucho más rápidos para poder emular el sistema. Podéis leer aquí el caso de cómo emular una SNES puede llevarse por delante un procesador de 3GHz. Y aun así, será inexacto.
¿Qué es una FPGA?
Una FPGA es un chip en cuyo interior hay muchos componentes electrónicos cuyas conexiones son libres. Estos componentes son desde muy pequeñitos como flip flops (memorias de un solo bit) hasta memorias más grandes o incluso CPUs modernas (modernas sí, pero pequeñas). La mayoría de los componentes de la FPGA son bloques elementales de la electrónica digital. Son piezas muy pequeñas (puertas AND, OR, flip flops, sumadores, algún divisor) que el diseñador electrónico necesita unir para crear circuitos.
Dentro de los chips del ordenador de la imagen también se encuentran estas mismas piezas. La diferencia clave está en que en los chips del ordenador original esas piezas están conectadas con un metal que no se puede cambiar una vez fabricado. Mientras que en la FPGA la conexión es variable. Y aquí viene lo fascinante. Con la FPGA adecuada, es posible reconstruir el circuito electrónico original y por lo tanto tener el mismo sistema, solo que en un solo chip. Así que una FPGA no imita lo que hacía el sistema original. Una FPGA es como el sistema original. Por supuesto, en la recreación del circuito se pueden cometer errores o puede faltar información y ahí surgirán pequeñas diferencias. Pero el potencial de llegar a ser exactamente igual al original con precisión superior al microsegundo está ahí.
¿Cómo se programa una FPGA?
El término programar es confuso. Programar una FPGA realmente se refiere a transferir la información de las conexiones desde el ordenador, donde se ha desarrollado el sistema, hasta el chip de la FPGA. Una vez programada, la FPGA contiene las conexiones que el ingeniero quiere.
¿Cómo decide el ingeniero esas conexiones? Dado que para cada modelo de FPGA hay unos bloques elementales en su interior, el ingeniero puede decidir directamente qué bloque usar y a qué bloque conectarlo. Como quien une los puntos de un dibujo. Sin embargo, este enfoque no es el más práctico. El ingeniero prefiere escribir un código parecido al de un programa de ordenador. Este código describe lo que el circuito tiene que hacer. Aunque parezca un programa, no es realmente un programa porque no existe un procesador que lo ejecute. En vez de eso, el ordenador con el que trabaja el ingeniero transformará ese código (ese fichero de texto) en unas conexiones en la FPGA tales que la FPGA se convierta en un circuito que haga la función que el ingeniero había descrito. Esto, que suena como si el proceso de transformación requiriese mucho ingenio por parte del ordenador, en realidad no lo es tanto. Lo más complicado del proceso no es pasar de la descripción a los bloques electrónicos sino conectarlos de forma que la señal se transmita adecuadamente entre ellos.
Así que, si un ingeniero escribe una descripción de un procesador, por ejemplo un Z80, este procesador podrá realizarse en los circuitos de muchos modelos distintos de FPGA y con el mismo código, también en un chip de verdad. Todos los procesadores y sistemas electrónicos digitales modernos están diseñados utilizando estos lenguajes de descripción (Verilog, principalmente) y el que acaben en un chip dedicado, con conexiones fijas, o en una FPGA, con conexiones variables; depende del tamaño de mercado para el que se fabrican y de su velocidad, fundamentalmente.
Resumiendo: en una FPGA se reconstruye el circuito original y, a efectos electrónicos, nos encontramos ante el mismo sistema que el original. Hasta los detalles más insignificantes y las particularidades más meticulosas de un sistema se pueden recrear en la FPGA y a menudo ocurrirán como consecuencia natural del circuito que se monta en ella. Sin embargo en un emulador el programador necesita elegir qué aspectos de la máquina original va a imitar y de qué manera. Los aspectos que no se noten en la emulación no se replican en un emulador. Sin embargo en la FPGA, por ser el circuito electrónico, es necesario incluir prácticamente todos los elementos que ocurrían en el original.
¿Ventajas de una FPGA frente a un emulador?
A estas alturas debería resultar obvio: la FPGA es, básicamente, el sistema original. Así que comparar el emulador con la FPGA es muy similar a compararlo con el original. Eso sí, la FPGA habitualmente puede hacer cosas que el sistema original no puede:
- Acceso a más RAM
- Lectura de discos desde una tarjeta SD
- Incrementar la velocidad de la CPU o de la memoria
- Otros trucos dado el acceso directo al hardware del que dispone
Y puede hacer algo que los emuladores tienen casi por imposible: conectarse a hardware real de la época, como el caso de los puertos MIDI del Mist o los puertos de cartucho del One Chip MSX.
Y hasta aquí este repaso sobre FPGAs y emulación.
YM3012 relación entrada/salida medida en silicio
La salida del YM2151 es una señal digital de 16 bits: 3 sin valor, 10 de mantisa y 3 de exponente. Los dos canales (izquierda y derecha) se transmiten secuencialmente. Este formato está relativamente detallado en la hoja de datos del YM2151 y del DAC que lo acompañaba, el YM3012. Sin embargo, dado que los dos chips eran de Yamaha y cuyo uso era ir el uno con el otro, Yamaha nunca explicó demasiado bien cómo funcionaban. Seguramente nadie usó nunca un YM2151 sin un YM3012 y viceversa. Pero poder extraer sonido de un YM2151 sin el YM3012 hace falta saber primero qué hacía este exactamente. Y para eso, nada mejor que unas medidas.
Con VDD=5.17V realicé medidas para cada valor del exponente (del 1 al 7) y para los siguientes valores de mantisa: $00, $0F, $3F, $FF, $100, $10F, $13F, $1FF, $200, $20F, $21F, $2FF, $300, $30F, $31F, $33F, $3FF. A partir de las medidas, caractericé la relación entrada salida así: Vout = n + m * d. Donde d es el valor de la mantisa y n,m son valores que dependen del exponente según esta relación:
exponente | n | m |
1 | 2.559 | 0.039*0.001 |
2 | 2.530 | 0.082*0.001 |
3 | 2.493 | 0.163*0.001 |
4 | 2.417 | 0.314*0.001 |
5 | 2.252 | 0.636*0.001 |
6 | 1.932 | 1.261*0.001 |
7 | 1.290 | 2.522*0.001 |
Para cada valor de exponente, la m (es decir, la sensibilidad o el tamaño del LSB) cambia en un factor 2. Pero el corte con cero, la n, también varía. La relación es de tal forma que empezando por exp=7 la salida varía desde 1.289V (d=0) hasta 3.870V (d=3FF), para exp=6 el rango se acorta a 1.937 (d=0) hasta 3.220 (d=3FF), para exp=5 el rango es 2.250 (d=0) hasta 2.900 (d=3FF) y así sucesivamente.
Lo que esto significa es que la señal está centrada alrededor de VDD/2. Para exp=7 se accede a todo el rango de señal desde VDD/4 hasta VDD*3/4 con una resolución de 10 bits. Al pasar a exp=6 el rango se acorta de forma simétrica alrededor de VDD/2 y se divide de nuevo en 10 bits. Es decir, la mitad central del rango goza de mayor resolución. Para exp=5 el rango vuelve a dividirse y a aumentar la resolución y así sucesivamente.
Esto explica la implementación del YM3012 en Verilog de Tatsuyuki Satoh. Cuyo meollo es este:
module dac3012(
CLK,CLKEN,
SO,SH1,SH2,
L,R
);
input CLK;
input CLKEN;
input SO,SH1,SH2;
output [15:0] L,R;
/////////////////////////////////////////////////////////////////////////////
// capture
/////////////////////////////////////////////////////////////////////////////
reg [12:0] sreg;
reg last_sh1,last_sh2;
reg [15:0] dr,dl;
reg [ 2:0] sr,sl;
reg [15:0] out_r,out_l;
always @(posedge CLK)
begin
if(CLKEN)
begin
// shift register
sreg <= {SO,sreg[12:1]};
last_sh1 <= SH1;
if(last_sh1 & ~SH1)
begin
out_r <= dr;
sr <= sreg[12:10];
dr <= {~sreg[9],sreg[8:0],6’b000000};
end else if(sr<7)
begin
// increment floating point
sr <= sr + 1;
dr[14:0] <= dr[15:1];
end
last_sh2 <= SH2;
if(last_sh2 & ~SH2)
begin
out_l <= dl;
sl <= sreg[12:10];
dl <= {~sreg[9],sreg[8:0],6’b000000};
end else if(sl<7)
begin
// increment floating point
sl <= sl + 1;
dl[14:0] <= dl[15:1];
end
end
end
/////////////////////////////////////////////////////////////////////////////
// output
/////////////////////////////////////////////////////////////////////////////
assign L = out_l;
assign R = out_r;
endmodule
La inversión del bit D[9] es una forma rápida de sumar 512 al valor para centrarlo en torno a un imaginario VDD/2. Luego divide el valor entre 2 conservando el signo para cada valor de exp distinto de 7.
Esta implementación no se corresponde, creo, fielmente a la relación E/S medida en el chip. En principio, para exp=7 entiendo que no hay que hacer nada especial y se puede guardar el valor tal cual en 16 bits:
linear[15:0] <= { data[9:0], 6'd0 };
Para los demás valores distintos hay que dividir por 2 y sumar 256:
linear[15:0] <= { 10'h100, 6'd0 } + { 1'b0, linear[15:1] };
en iteraciones sucesivas a la manera de actuar de Satoh.
Comentarios recientes