header-logo

Comunicación de marketing impulsada por inteligencia artificial

iCrowdNewswire Spanish

Cómo los emuladores de SNES obtuvieron unos cuantos píxeles de la perfección completa

Apr 3, 2020 2:38 AM ET

Bsnes necesita su ayuda para decodificar algunos chips PPU de tres décadas de edad.

NES está diseñado para realizar diversas tareas en ciertas frecuencias y tiempos.

Si imagina un reloj de 100 Hz, es un dispositivo con un pin digital que pasa a la lógica alta (+5 voltios, por ejemplo) y luego de nuevo a la lógica baja (0 voltios, o tierra) 100 veces por segundo. Así que cada segundo, la tensión del pin fluctuará 200 veces en total: 100 bordes de reloj en aumento y 100 bordes de reloj que caen.

Un ciclo de reloj se trata generalmente como una transición completa, por lo que un reloj de 100 Hz generaría 100 ciclos de reloj por segundo. Hay algunos sistemas que requieren distinguir entre bordes ascendentes y descendentes, y para aquellos, desglosamos esto más abajo en medio ciclos para denotar cada fase (alta o baja) de la señal de reloj.

El objetivo clave de un emulador auténtico es realizar tareas exactamente de la misma manera y exactamente en los mismos momentos que el hardware real. No importa mucho específicamente cómo se realizan las tareas. Lo único que importa es que el emulador, al recibir las mismas entradas, genera las mismas salidas con la misma sincronización que el hardware real.

Tiempo

A veces, las operaciones ocurren con el tiempo. Tomemos la multiplicación de CPU SNES, por ejemplo. En lugar de hacer una pausa para esperar a que se complete la multiplicación, la CPU SNES calcula el resultado de la multiplicación un bit a la vez en segundo plano sobre ocho ciclos de código de operación de CPU. Esto permite que el código posiblemente haga otras cosas mientras espera a que se complete la multiplicación.

Cualquier software lanzado comercialmente es probable que espere esos ocho ciclos, porque si intenta leer el resultado antes de que esté listo, obtendrá un resultado parcialmente calculado en su lugar. Sin embargo, los emuladores de SNES anteriores dieron resultados correctos inmediatamente,sin esperar a estos ciclos adicionales.

Cuando los aficionados comenzaron a crear y probar el software homebrew a través de emuladores, esta discrepancia comenzó a causar algunos problemas. Algunos de este software, como muchos de los primeros hacks De Súper Mario World ROM, sólo funcionaba correctamente en estos emuladores anteriores, y no en hardware SNES real. Esto se debe a que se diseñaron teniendo en cuenta los resultados de multiplicación inmediatos (e inauténticos a reales) en el emulador.

A medida que los emuladores mejoraron, este viejo software se rompió, y hemos tenido que ofrecer posteriormente opciones de compatibilidad en nuestros emuladores más nuevos con el fin de no perder este software al tiempo. Sí, por muy surrealista que sea decir, ¡hoy en día nuestros emuladores tienen que emular otros emuladores! ¡Qué meta!

Lo bueno del retardo de multiplicación de la CPU es que es muy predecible: los ocho ciclos de cálculo comienzan inmediatamente después de solicitar una multiplicación. Al escribir código para leer los resultados después de cada ciclo, pudimos confirmar que la CPU SNES estaba utilizando el algoritmo Booth para la multiplicación.

Sincronización de reloj

Otras operaciones no son tan sencillas de modelar, ya que se producen de forma asincrónica en segundo plano. La actualización dRAM de la CPU SNES es uno de estos casos.

Durante la representación de cada línea de exploración, en un momento dado, toda la CPU SNES se bloquea durante un corto período de tiempo a medida que se actualiza el contenido del chip RAM. Esto es necesario porque, como medida de reducción de costos, el SNES utilizaRAM dinámico (en lugar de RAM estática) para su memoria principal de la CPU. La RAM dinámica debe actualizarse periódicamente para conservar su contenido a lo largo del tiempo.

For a truly perfect emulator, just making ~3,500 commercially released SNES games playable isn't enough. Every function of the system has to be simulated with cycle-perfect accuracy, too.
Ampliar / Para un emulador verdaderamente perfecto, sólo hacer 3.500 juegos SNES lanzados comercialmente jugables no es suficiente. Cada función del sistema tiene que ser simulada con precisión de ciclo perfecto, también.

La información clave para averiguar el momento preciso de estas operaciones fue aprovechar los contadores horizontales y verticales de la PPU de SNES. Estos contadores avanzan y se restablecen después de cada período de vaciado horizontal y vertical. Sin embargo, su precisión es sólo una cuarta parte de la frecuencia del oscilador de CPU del SNES; es decir, el contador horizontal aumenta sólo una vez cada cuatro ciclos de reloj.

Al leer los contadores varias veces, pude determinar con qué cuarto de ciclo de reloj se alineó el contador. Al combinar esa visión con una función especialmente diseñada que podría pasar por un número preciso, especificado por el usuario de ciclos de reloj, se hizo posible alinear perfectamente la CPU SNES a cualquier posición exacta del ciclo de reloj que quería.

Al iterar sobre un rango de ciclos de reloj en un bucle, pude determinar exactamente cuándo se producirían ciertas operaciones (como la actualización de DRAM, transferencias HDMA, sondeo de interrupción, etc.), y pude reproducir esto precisamente bajo emulación.

El chip SMp SNES también tiene sus propios temporizadores, y la ingeniería inversa similar también tuvo éxito contra ese procesador. Podría pasar un artículo entero hablando del registro SMP TEST solo, lo que permite a los codificadores controlar el divisor de reloj del SMP y sus temporizadores, entre otras cosas horribles. Baste decir que, si bien no fue un proceso fácil o rápido, finalmente fuimos victoriosos.

Recopilación de coprocesadores

The SuperFX chip is just one of many cartridge coprocessors that an SNES emulator has to handle correctly.
Ampliar / El chip SuperFX es sólo uno de los muchos coprocesadores de cartucho que un emulador de SNES tiene que manejar correctamente.

Había una gran cantidad de coprocesadores SNES utilizados dentro de varios cartuchos de juego que necesitaban ser domesticados también. Desde CPU de uso general dedicadas como las SuperFX y SA-1,hasta procesadores de señal digital como el DSP-1 y el Cx4, hasta aceleradores de descompresión como el S-DD1 y el SPC7110, hasta relojes en tiempo real de Sharp y Epson, y más…

Eso significa que un emulador de SNES debe ser capaz de manejar las memorias caché de instrucciones y píxeles de SuperFX; el árbitro de conflicto de bus de memoria de la SA-1 (que permitió que la CPU SNES y SA-1 compartan simultáneamente los mismos chips ROM y RAM); el firmware integrado del DSP-1 y del Cx4; los codificadores aritméticos basados en predicciones del S-DD1 y el SPC7110; y los casos de borde BCD (decimal codificado en binario) impares de los relojes en tiempo real. Lenta pero seguramente, aplicando las técnicas anteriores para determinar la corrección y el tiempo, pudimos emular casi perfectamente todos estos chips.

En realidad se necesitó un esfuerzo masivo y miles de dólares para decap y extraer el firmware de programación de los procesadores de señal digital utilizados en varios juegos. En un caso, la emulación del NEC uPD772x llevó a que el código de higan se utilizara para salvar la voz del difunto profesor Stephen Hawking!

En otro caso, tuvimos que realizar ingeniería inversa de todo el conjunto de instrucciones de la arquitectura Hg51B de Hitachi, porque esta arquitectura nunca fue documentada públicamente. En otro, un juego (Hayazashi Nidan Morita Shougi 2) terminó conteniendo una CPU ARM6 de 32 bits y 21 MHz para acelerar su motor de ajedrez japonés!

Preservar todos los coprocesadores de SNES por sí solos

fue un viaje de varios años lleno de desafíos y sorpresas.

Procesamiento de señal digital

No debe confundirse con el coprocesador de cartucho DSP-1, el chip S-DSP (procesador de señal digital) de Sony es lo que generó el sonido distintivo del SNES. Este chip combinó ocho canales de voz con codificación ADPCM de 4 bits para producir una señal estéreo de 16 bits.

En la superficie, y según el diagrama del sistema de anterior, el DSP inicialmente se ve como una caja negra: usted configura los canales de voz y los ajustes del mezclador y se sente a medida que genera el sonido para ser enviado a sus altavoces.

Pero una característica clave permitió a un desarrollador por el nombre de blargg realizar ingeniería totalmente inversa de este chip: el búfer de eco. El DSP SNES tiene una característica que mezcla las salidas de las muestras anteriores juntas para producir un efecto de eco. Esto sucede al final del proceso de generación de audio (aparte de una última marca de silencio final que se puede aplicar para silenciar toda la salida de audio.)

Al escribir código cuidadosamente cronometrado en el ciclo y monitorear esos resultados de eco, se hizo posible descubrir el orden exacto de las operaciones que el DSP de SNES tomaría para generar cada muestra y producir audio de precisión de ciclo y bit perfecto.

Preservar los PpUs

Todo esto nos lleva a la pieza final del diagrama arquitectónico de SNES: los chips PPU-1 y PPU-2. Gracias a John McMaster, tenemos 20 escaneos de aumento de los chips S-PPU1 (revisión 1) y S-PPU2 (revisión 3).

Los escaneos de troquel anteriores resaltan que obviamente no son CPU de uso general, ni son arquitecturas personalizadas que ejecutan códigos de operación de una ROM de programa de firmware interno. Ambos son circuitos lógicos dedicados y codificados de forma rígida que toman las entradas de varios registros y memoria y producen la salida de vídeo a su monitor, una línea de exploración a la vez.

La razón por la que los PPU siguen siendo la frontera final de la emulación SNES es porque, a diferencia de todos los componentes discutidos hasta ahora, los PPU son realmente una caja negra. Puede configurarlos en cualquier estado que desee, pero la CPU SNES no tiene forma de observar directamente lo que generan.

Para usar nuestro ejemplo de multiplicación anterior como analogía, imagine si solicitó el resultado de 3 * 7, pero en lugar de recibir una respuesta binaria, en su lugar recibió una imagen difusa y analógica que muestra los números ’21’ en la pantalla en su lugar. Cualquier persona que ejecute su software podría ver el 21, pero no podía escribir un programa de prueba para confirmar automáticamente que estaban viendo la respuesta correcta. La verificación humana manual de este tipo de resultado no escala más allá de unos pocos miles de pruebas, y vamos a necesitar varios millones para realmente perfeccionar el comportamiento exacto de pPU.

Ahora sé lo que probablemente estás pensando: “Pero byuu, ¿no sería fácil usar una tarjeta de captura, realizar un montón de procesamiento de imágenes, más o menos emparejarlo con la imagen de pantalla digital del emulador, y pasar-fallar la prueba basada en eso?”

Bueno, ¡probablemente! Especialmente si la prueba fuera tan simple como dos números gigantes que abarcan todo el tamaño de la pantalla.

Pero, ¿qué pasaría si nuestras pruebas fueran muy matizadas, y estábamos tratando de detectar una diferencia de color a media sombra de un solo píxel? ¿Y si quisiéramos hacer un millón de pruebas consecutivas y no necesariamente sabéis lo que iban a generar todavía, pero aún así queríamos igualarlo con el resultado de nuestra emulación?

Nada supera la comodidad y la certeza de los datos digitales, un flujo exacto de bits que usted hace coincidir o no coinciden. El dominio analógico de las imágenes CRT no proporciona eso.

¿Por qué importa esto?

Con la excepción de un juego (Air Strike Patrol), todo el software SNES con licencia oficial está (destinado a ser) scanline basado. Estos juegos no intentan cambiar el estado de representación de PPU en medio de una línea de exploración de representación activa (un truco de programación conocido como “efecto ráster”). Eso significa que el momento de ejecutar la gran mayoría de los juegos no tiene que ser increíblemente preciso; siempre y cuando estés listo a tiempo para la próxima línea de escaneo completa, estás bien.

Pero sí importa para este juego.

Arriba, verá que el texto “Buena Suerte” en la Patrulla de Ataque Aéreo está siendo girado de un fotograma a un fotograma. El juego hace esto modificando la posición de desplazamiento vertical de la capa de fondo 3 (BG3). Sin embargo, la pantalla HUD de la izquierda (donde muestra que tiene 39 misiles disponibles) también está en la misma capa de fondo.

El juego gestiona esta división cambiando la posición de desplazamiento de BG3 después de que el HUD de la izquierda se haya renderizado, pero antes de que el texto “Buena Suerte” comience a renderizarse en cada línea de exploración. Puede salirse con la suya porque BG3 es transparente fuera del HUD y el texto, por lo que no hay nada que dibujar realmente entre esos dos puntos, independientemente del valor del registro de desplazamiento vertical. Este comportamiento nos indica que los registros de desplazamiento se pueden cambiar en cualquier momento durante la representación.

That little shadow below the plane here causes an untold number of headaches for an accuracy-obsessed emulator maker.
Esa pequeña sombra debajo del avión aquí causa un número incalculable de dolores de cabeza para un fabricante de emuladores obsesionado con la precisión.

Arriba está la infame sombra de plano cerca de la parte inferior de la pantalla. Este efecto se representa cambiando el registro de brillo de la pantalla para ráfagas cortas en el lapso de cinco líneas de exploración.

Mientras juegas, notarás que la sombra es bastante errática. En la imagen anterior se ve un poco como una ‘c’, pero el marco para enmarcar la forma cambia constantemente en longitud y punto de inicio para cada línea de exploración. Patrulla de Ataque Aéreo sólo apuntó en el estadio general de béisbol de donde querían que apareciera la sombra, y luego fue a por ello, armas ardiendo. En su mayoría funcionó.

Emular ese comportamiento correctamente requiere un tiempo de ciclo perfecto que es extremadamente difícil de conseguir absolutamente correcto en un emulador.

The <em>Air Strike Patrol</em> pause screen uses raster effects that weren't intentionally used in any other SNES game.
La pantalla de pausa de Air Strike Patrol utiliza efectos ráster que no se utilizaron intencionalmente en ningún otro juego de SNES.

Por último, aquí está la pantalla de pausa. Este activa BG3 durante el borde amarillo y negro a la izquierda, y se apaga de nuevo durante el mismo borde a la derecha, para dibujar las líneas grises en la pantalla. También alterna qué líneas de exploración muestran estas líneas grises cada dos fotogramas para crear un efecto de agitación para la superposición.

Si hace zoom en la imagen emulada anterior, notará que faltan algunos píxeles en el borde izquierdo de estas líneas grises para un par de líneas de exploración. Eso es porque mi emulación de la PPU no es cien por ciento ciclo perfecto. En este caso, está activando el efecto de alternancia BG3 un poco más tarde de lo que se supone que debe.

Podría ajustar fácilmente los tiempos para renderizar esta imagen correctamente. Pero ese ajuste es igual de probable que tenga efectos adversos en otros títulos que modifican los registros de visualización de PPU a mitad de la línea de exploración. Mientras que la Patrulla de Huelga Aérea es el único juego para hacer esta intención

aliado, hay al menos una docena de juegos que lo hacen accidentalmente (tal vez tuvieron un incendio IRQ un poco tarde o demasiado tarde).

A veces esto produce una corrupción breve y visible que se pasó por alto en el desarrollo (como con Full Throttle Racing cuando se realiza la transición entre la tienda y el juego). A veces las escrituras ocurren durante una parte de la pantalla transparente y por lo tanto no causan anomalías visuales (como con la pantalla de estado HP en Dai Kaijuu Monogatari II.) Sin embargo, incluso estos casos de borde “invisibles” pueden causar problemas con los renderizadores de líneas de exploración menos precisos utilizados en emuladores de más rendimiento.

Incluso descontando Air Strike Patrol,todos estos efectos ráster accidentales (pero efectivos) en el software SNES hacen que sea funcionalmente imposible diseñar un renderizador PPU que genere una línea de exploración completa con una precisión perfecta para el ciclo.

Con bsnes, a través de años de prueba y error, he creado una lista de estos juegos de “efecto ráster”. También he diseñado posiciones de renderizado personalizadas que permiten que un renderizador basado en líneas de escaneo mucho más rápido muestre todos estos juegos correctamente (excepto para Air Strike Patrol,por supuesto). Estos esencialmente equivalen a hacks insatisfactorios por juego, sin embargo.

También tengo un renderizador pPU basado en ciclos que no necesita ninguno de estos hacks, pero finalmente causa pequeñas diferencias de uno a cuatro píxeles con hardware real, como en la última captura de pantalla de Air Strike Patrol que se muestra arriba.

Registros internos de enclavamiento

La causa de estas pequeñas fallas se reduce a los tiempos de comportamiento de bloqueo.

Supongamos que el SNES está renderizando su icónico modo 7,que es una transformación de textura afín con ajustes de parámetros por línea de escaneo. Para determinar cualquier píxel dado en la pantalla, se puede realizar un cálculo como este:

px á a * clip (hoffset - hcenter) + b * clip(voffset - vcenter) +
b * y + (hcenter << 8)

py á c * clip(hoffset - hcenter) + d * clip(voffset - vcenter) +
d * y + (vcenter << 8)

Un SNES real tendría problemas para realizar estas seis multiplicaciones lo suficientemente rápido para cada píxel representado en un fotograma. Pero ninguno de estos valores cambia de píxel a píxel (o al menos, no se supone que lo hagan), por lo que solo tenemos que calcular px y py una vez al principio de cada línea de exploración. Por lo tanto, el PPU almacena en caché los resultados estáticos en pestillos, que son esencialmente copias de registros PPU que pueden haber sido transformados o pueden transformarse más a medida que pasa el tiempo.

Las coordenadas x,y se transforman por el modo 7 así:

Buey (px + a * x) >> 8

oy á (py + c * x) >> 8

Aunque x cambia cada píxel, sabemos que aumenta en uno cada vez. Al mantener los acumuladores internos, simplemente podemos agregar valores constantes a y c a buey y oy una vez cada píxel, en lugar de tener que realizar dos multiplicaciones para cada píxel.

La pregunta entonces se convierte, ¿en qué posición exacta del ciclo la PPU lee los valores a y c de los registros externos SNES PPU accesibles por CPU?

Si adivinamos un tiempo demasiado pronto, puede romper un cierto subconjunto de juegos. Si adivinamos un tiempo demasiado tarde, puede romper un subconjunto diferente de juegos.

El enfoque fácil es simplemente seguir esperando informes de errores y ajustar estas posiciones para resolver problemas en cualquier juego específico. Pero al hacer esto, nunca encontraremos las posiciones exactas, sólo las aproximaciones.

Y cada vez que cambiemos una de estas variables, no vamos a ser capaces de volver a probar toda la biblioteca SNES de 3.500 juegos para detectar cualquier regresión que nuestros cambios puedan haber causado.

Emulación Whack-a-Mole

Artist's conception of the process of fixing emulation errors.
Ampliar / Concepción del artista del proceso de corrección de errores de emulación.

Este estilo de “simplemente conseguir el juego actual de interés trabajando a cualquier costo” metodología de prueba llevó a un fenómeno que llamo Emulación Whack-a-Mole.

En los primeros días de la emulación de SNES, cada vez que un juego tenía problemas, cualquier arreglo que resultara en un juego determinado de trabajo sería aceptado y comprometido con el emulador. Sin falta, esa corrección terminaría rompiendo un juego diferente. Y cuando se solucionó ese juego, un tercer juego fallaría. Arreglar el tercer juego luego rompería el primer juego de nuevo. Esto se continuó durante años.

El error que se cometió aquí fue tratar de considerar sólo una variable a la vez. Digamos que tenemos un juego donde un evento tiene que ocurrir entre el ciclo 20 y 120 para trabajar. No sabemos el ciclo exacto, así que seguimos adelante y elegimos 70, justo en el medio.

Más tarde un informe de error viene en un juego diferente, y determinamos que para que este juego funcione, el valor del ciclo debe estar entre 10 y 60. Así que ahora lo ajustamos a 40, que funciona para ambos juegos. ¡Parece sensato!

Pero luego viene un tercer juego que necesita el evento para desencadenar entre los ciclos 80 y 160! Ahora no hay manera de conseguir que los tres juegos funcionen al mismo tiempo con un solo valor.

Esto llevó a los emuladores a implementar hacks específicos del juego. No quieres ser la persona que va a enviar el emulador que no ejecuta Mario, Zeldao Metroid. Así que usted utiliza 40 para el caso general, pero fuerza el valor de sincronización para ser 100 en su lugar cuando Metroid se carga.

¿Cómo es posible que dos juegos necesiten valores diferentes? Esto se debe a que hay más de una sola variable en juego. El tiempo que utilice para desencadenar un evento diferente anteriormente puede influir en qué valor de sincronización se necesita para el siguiente evento.

Para decirlo como una expresión algebraica simple, imagine:

2x + y á 120

Usted puede resolver esta ecuación con x-10, y-100. O con x-20, y-80. O con x-30, y-60. Si sólo estás pensando en qué valores de x hace que tu subconjunto de juegos funcione simultáneamente, entonces es posible que te pierda el hecho de que el problema real es que tu variable y es incorrecta!

Los primeros emuladores simplemente anularían el valor de x en función del juego que se está jugando, con el fin de ser más compatibles. Esos hacks por juego persistieron incluso si un valor correcto y singular para x se dio a conocer más tarde. Por lo tanto, el problema con y nunca sería descubierto!

Con el SNES, sin embargo, no es sólo una o dos variables en juego a la vez. La PPU de SNES por sí sola tiene 52 registros externos que comprenden la configuración de 130. El proceso de renderización de una línea de exploración implica todos los ajustes de 130 y un número desconocido de registros internos y bloqueados, todo en juego al mismo tiempo. Es demasiado para cualquier persona en el exterior para comprender completamente todo el estado de la PPU SNES en un momento dado en el tiempo.

Este es un aspecto de la emulación que no es intuitivo para los forasteros, pero muy cierto: la precisión no es lo mismo que la compatibilidad. Podrías tener un emulador que sea 99 por ciento preciso, pero solo ejecutes el 10 por ciento de los juegos. Y usted podría tener un emulador que es sólo 80 por ciento preciso, sin embargo, ejecutaría 98 por ciento de los juegos. A veces, hacer las cosas bien romperá los juegos populares a corto plazo. Este es un sacrificio necesario si alguna vez esperas lograr tanto una precisión del 100 por ciento como una compatibilidad del 100 por ciento.

Averiguarlo

La forma en que hemos conseguido la emulación de PPU de SNES hasta el punto en que está ahora ha sido a través de razonamiento deductivo y resultados del mundo real.

Sabemos que los PpUs tienen acceso a dos chips VRAM. Sabemos que sólo pueden leer tantos bytes de datos de cada chip por línea de exploración. Conocemos los amplios detalles de cómo funciona cada modo de vídeo SNES. Y con eso, podemos diseñar un patrón general de cómo podría verse un diseño. Este es un ejemplo abreviado de cómo podrían funcionar los tres primeros modos de vídeo de SNES, por ejemplo:

if(io.bgMode ? 0) á

bg4.fetchNameTable();

bg3.fetchNameTable();

bg2.fetchNameTable();

bg1.fetchNameTab

le(); bg4.fetchCharacter(0); bg3.fetchCharacter(0); bg2.fetchCharacter(0); bg1.fetchCharacter(0); } if(io.bgMode ? 1) ? bg3.fetchNameTable(); bg2.fetchNameTable(); bg1.fetchNameTable(); bg3.fetchCharacter(0); bg2.fetchCharacter(0); bg2.fetchCharacter(1); bg1.fetchCharacter(0); bg1.fetchCharacter(1); } if(io.bgMode ? 2) bg2.fetchNameTable(); bg1.fetchNameTable(); bg3.fetchOffset(0); bg3.fetchOffset(8); bg2.fetchCharacter(0); bg2.fetchCharacter(1); bg1.fetchCharacter(0); bg1.fetchCharacter(1); }

Agujeros en la caja negra

La PPU expone un poco de su estado a observadores externos: indicadores de vaciado horizontales y verticales, contadores de píxeles horizontales y verticales y marcas de “rango-teselas sobre” para sprites. No es mucho, pero de nuevo, cada poco de estado expuesto ayuda.

La VRAM (RAM de vídeo) de la PPU de SNES está bloqueada de la CPU SNES durante la renderización, incluso para su lectura. Pero resulta que el OAM (memoria de sprites) y CGRAM (memoria de paleta) no lo son. La captura es que el PPU De SNES controla el bus de direcciones durante este tiempo. Por lo tanto, al leer OAM y CGRAM mientras la pantalla está renderizando, soy capaz de observar lo que la PPU SNES está obteniendo de estas dos piezas de memoria durante este tiempo crucial.

No es todo el rompecabezas, pero fue suficiente de una pieza para mí para implementar patrones de captura de sprites en su mayoría correctos.

Usando los patrones de acceso OAM y CGRAM expuestos, banderas PPU, observaciones generales (leer: adivinar) de informes de errores en varios juegos, y algunos razonamientos deductivos han llevado a renderizadores PPU basados en ciclos que casi pueden ejecutar todos los juegos lanzados comercialmente perfectamente.

Pero sigue siendo un hogar de cartas: si alguien empezara a crear homebrew que explota el tiempo de ciclo perfecto y los efectos ráster, todos nuestros emuladores hoy en día comenzarían a desmoronarse. Esto incluye implementaciones basadas en software y FPGA por igual.

Quiero ser claro aquí: todo el mundo está adivinando actualmente el orden interno de las operaciones y los comportamientos de enclavamiento de las PPU de SNES. Nadie sabe cómo emular esto perfectamente. Aún no, de todos modos.

Posibles soluciones

Entonces, ¿qué hacemos al respecto? ¿Cómo determinamos el orden exacto de las operaciones de la PPU de SNES, cuando actúa como una caja negra para nosotros desde el lado de la CPU SNES de las cosas?

Veo cuatro posibilidades: analizadores lógicos, salida de vídeo digital en modo de prueba, placas de ruptura y decapado.

Analizadores lógicos

Si nos fijamos en los escaneos de troquel PPU desde arriba, notarás almohadillas negras alrededor de los bordes de las fichas. Estas son almohadillas que se conectan a los pines en los chips reales.

Estos pines mantienen el estado de los PpUs durante cada ciclo de reloj de ejecución. Aquí encontrará la dirección actual a la que acceden para el chip RAM de vídeo, qué valor de datos se transmite de una PPU a la otra, y más.

Esta es información que no está disponible para el código que se ejecuta en la CPU SNES, pero proporciona información valiosa sobre el orden interno de operaciones de la PPU de SNES.

Hooking a Super NES PPU to a logic analyzer like this could be the key to opening the
Ampliar / Enganchar una PPU Super NES a un analizador lógico como este podría ser la clave para abrir la “caja negra”.

El problema crítico con los analizadores lógicos es que no está muy bien controlado: intentar muestrear datos en directo en un sistema en ejecución va a darle una secuencia de resultados que son bastante difíciles de descifrar. También se encontrará con el mismo problema que intentaría analizar la salida RGB analógica del sistema: tendrá que ejecutar manualmente todas y cada una de las pruebas para capturar estos datos. No es un buen sistema para crear pruebas de regresión automatizadas reproducibles.

Salida de vídeo digital en modo de prueba

Recientemente, gracias a los escaneos de imágenes de matriz de 20x, se descubrió un modo de prueba secreto con las PTU de SNES. Al realizar una pequeña modificación de hardware, las PTU SNES comenzarán a emitir una señal RGB digital de 15 bits!

¡Esto es casi exactamente lo que necesitamos! Sin embargo, este modo tiene varios problemas, como el famoso modo 7 no emitir una imagen correcta en este modo. Parece que esta característica nunca se completó completamente.

Además, esto todavía requeriría la modificación manual de las consolas SNES y la construcción de un mecanismo adecuado para capturar la salida del modo de prueba y analizarla. Aún así, a diferencia de la solución de captura RGB analógica, esta señal digital tiene el potencial de someterse a pruebas automáticas, lo que podría permitirnos completar rápidamente una gran parte del trabajo de ingeniería inversa de PPU.

Tableros de ruptura

Dado que las PTU SNES son estáticas, sería posible extraer las PTU de una consola SNES en funcionamiento y colocarlas en un protoboard o PCB personalizado junto con los dos chips VRAM. A partir de aquí, un microcontrolador podría sentarse entre las PpUs y una interfaz USB a un PC, lo que permitiría a un codificador programar todos los registros externos de RAM de vídeo y PPU. Por último, el codificador podría controlar manualmente el reloj PPU y muestrear los pines de E/S de PPU resultantes, los registros y la memoria durante cada ciclo.

Al modificar un emulador de software para generar estos mismos valores de pin de E/S internos, sería posible comparar directamente el hardware real con la emulación, incluso en tiempo real. Sin embargo, esto seguirá siendo un trabajo muy duro, ya que todavía no tenemos visibilidad de las operaciones internas de los PPU.

Decapping

Así que el enfoque final, el más extremo, sería ampliar nuestros esfuerzos de destapreo. Tenemos 20 escaneos de troqueles, pero la resolución no es suficiente para hacer y reconstruir circuitos lógicos individuales a partir de ellos, como se hizo con el proyecto Visual 6502. Si podemos obtener escaneos de aumento de 100x de ambos dados PPU, podríamos comenzar la ardua tarea de mapear la totalidad de los PpUs y convertirlos en netlists o código VHDL. Estos serían directamente utilizables con FPGA y podrían ser portados a C+ + u otro lenguaje de software utilizable con nuestros emuladores de software, así.

Una estimación del estadio que recibí de alguien que ha hecho un trabajo como este en el pasado es que tomaría alrededor de 600 horas hacer este mapeo para ambos PPUs. Eso está muy pasado del punto de “vamos a recaudar fondos y pagar a alguien para hacer esto” niveles y cae directamente en el territorio “esperemos que alguien extremadamente talentoso con un conjunto de habilidades única, en la demanda está interesado en el voluntariado para ayudarnos”.

Eso es, por supuesto, no decir que no estaría feliz de recompensar económicamente a nadie capaz de ayudarme, así como para pagar por cualquier parte o mano de obra requerida.

Una llamada de ayuda

En resumen, he llegado tan lejos como puedo con mi proyecto emulador de SNES, y necesito ayuda para terminar esta tarea final. Si has leído hasta aquí, ¡esperamos que puedas proporcionar esa ayuda! ¡Cualquier asistencia, incluidas las contribuciones a nuestro proyecto GitHub bsnes,o cualquier documentación de investigación sobre el funcionamiento interno de los PPU de SNES que se podrían crear, sería invaluable!

¡Muchas gracias por leer, y por el apoyo continuo de todos! Ha sido un honor haber sido parte de la comunidad de emulación de SNES estos últimos quince años.

Contact Information:

BYUU
Keywords:  afds, afdsafds

Tags:  Spanish, United States, Wire