Arquitectura de PlayStation
(copetti.org)- La arquitectura de PlayStation eligió una configuración simple y práctica para reducir la complejidad del desarrollo de hardware 3D, pero dejó en manos de los desarrolladores ciertas cargas y límites visuales en alineación gráfica, corrección de texturas y precisión
- El Sony CXD8530BQ es un SoC que integra un núcleo compatible con MIPS R3000A basado en CoreWare de LSI Logic, junto con CP0, GTE y MDEC; funciona a 33.87MHz y organiza el movimiento de datos alrededor de 2MB de RAM, 1KB de Scratchpad y DMA
- En gráficos, la GTE se encarga de la proyección 3D, iluminación y clipping, mientras que la GPU renderiza líneas, cuadriláteros y triángulos mediante comandos; sin Z-buffer, usa una ordering table, por lo que la CPU debe decidir el orden de los polígonos
- La GPU genera temblores, superposición y texture warping por usar affine texture mapping, nearest neighbour, coordenadas enteras y no tener resolución subpíxel, por lo que se usaban atajos como tessellation, reemplazo por color sólido y fondos pre-renderizados
- El diseño basado en CD-ROM, con 620MB de almacenamiento, streaming de audio ADPCM a 44.1kHz, entorno de ejecución basado en BIOS y protección anticopia con Wobble Groove combinada con bloqueo regional, cambió la forma de desarrollar y distribuir juegos
Diseño básico y CPU
- PlayStation apuntó a un diseño simple y práctico bajo la premisa de que el hardware 3D podía volverse difícil de desarrollar, aceptando ciertas limitaciones como costo de esa decisión
- El chip principal, Sony CXD8530BQ, equivale a lo que hoy llamaríamos un SoC, y usa un núcleo de CPU basado en CoreWare de LSI Logic compatible a nivel binario con la familia MIPS R3000A
- El núcleo de CPU tiene 33.87MHz, ISA MIPS I, palabras de 32 bits, 32 registros de propósito general, bus de datos de 32 bits, bus de direcciones de 32 bits, pipeline de 5 etapas y 4KB de caché de instrucciones
- No tiene caché de datos, y la memoria de 1KB que originalmente correspondería a esa caché se ofrece como Scratchpad mapeado a una dirección fija, para usarse como SRAM rápida
- El sistema ofrece 2MB de EDO RAM para tareas generales; la EDO RAM se describe como un tipo de chip un poco más eficiente y con menor latencia que la DRAM común
Bus y coprocesadores
- El bus de datos se divide en Main Bus de 32 bits y Sub Bus de 16/8 bits; el Main Bus conecta MDEC y GPU, mientras que el Sub Bus conecta el resto de los componentes y la E/S
- El controlador de CD-ROM, MDEC, GPU, SPU y el puerto paralelo pueden acceder al DMA controller, y DMA toma el control del bus principal para transferir datos con alto rendimiento sin pasar por la CPU
- Mientras DMA está activo, la CPU no puede acceder al bus principal y, si no hay trabajo para procesar en el Scratchpad, queda en espera
- El CP0, o System Control Coprocessor, administra la implementación de caché, el acceso directo al Scratchpad, el aislamiento de la caché de instrucciones, interrupciones, excepciones y breakpoints
- El CP2, o Geometry Transformation Engine, acelera cálculos de vectores y matrices basados en punto fijo, y se encarga de las primeras etapas del pipeline gráfico, como proyección 3D, iluminación y clipping
- MDEC descomprime macroblocks codificados de forma similar a JPEG a un formato que la GPU puede entender, y puede procesar 9,000 macroblocks por segundo de bitmaps 24bpp de 8×8 píxeles, permitiendo hacer streaming de FMV a 320×240px y 30fps
- No se incluye un FPU correspondiente a CP1, y los cálculos decimales deben hacerse con coma flotante por software o punto fijo, con limitaciones de velocidad y precisión
Pipeline y delay slots
- El pipeline MIPS I es vulnerable a control hazard y data hazard, y tiene el comportamiento de branch delay slot, donde la instrucción siguiente a un branch o jump siempre se ejecuta
- Las instrucciones
loadno detienen el pipeline hasta que el dato cargado esté listo, así que si la siguiente instrucción depende de ese resultado, hace falta un relleno para obtener el operando correcto - Algunos delay slots pueden llenarse con instrucciones útiles, por lo que no siempre implican ciclos desperdiciados
- Basado en la filosofía RISC de que compiladores y ensambladores de alta calidad deben encargarse de reordenar instrucciones o insertar rellenos, MIPS eligió exponer el pipeline de la CPU a desarrolladores y toolchains
- Ese diseño también tiene la desventaja de dificultar la compatibilidad hacia atrás a medida que aparecen nuevas microarquitecturas en generaciones posteriores de CPU
Pipeline gráfico
- Una parte importante del pipeline gráfico la procesa la GTE, y los datos resultantes se envían a la GPU propietaria de Sony para su renderizado
- El sistema almacena frame buffer, texturas y otros recursos de renderizado en 1MB de VRAM, y la CPU puede llenar esa región mediante DMA
- La VRAM de los modelos iniciales tenía estructura dual-ported y usaba dos buses de 16 bits, permitiendo acceso simultáneo de CPU, DMA, GPU y codificador de video
- En modelos posteriores se cambió a SGRAM con un único bus de datos de 32 bits, y por diferencias de timing algunos juegos tardíos como Jet Moto 3 pueden mostrar corrupción gráfica en sistemas basados en VRAM
- La CPU puede llenar hasta 3 comandos en el FIFO buffer de 64 bytes de la GPU para enviar datos geométricos; los comandos solicitan renderizado, cambios de configuración o manipulación de VRAM
- La GPU puede dibujar líneas, cuadriláteros y triángulos por separado, y los triángulos se usan como elemento base para construir modelos 3D complejos
- El sistema de coordenadas de la GPU usa coordenadas enteras donde cada coordenada corresponde al punto de muestreo en el centro de un píxel, y no utiliza coordenadas fraccionales
Visibilidad, rasterización y texturas
- La GPU de PlayStation no ofrece resolución de visibilidad por hardware, y usa una ordering table para administrar direcciones de comandos de GPU según el valor de profundidad
- La CPU primero ordena los polígonos, luego coloca referencias en la entrada adecuada de la tabla, y finalmente envía la tabla a la GPU por DMA para que renderice en el orden correcto
- La GPU solo necesita un único frame buffer, y el rasteriser convierte vértices en líneas, triángulos, cuadriláteros y píxeles
- Los triángulos son la primitive más compleja y versátil, con soporte para texturas y shading; las líneas son rápidas pero no sirven bien para superficies con textura, y los cuadriláteros están limitados a sprites de hasta 256×256 píxeles y no ofrecen shading ni efectos de transformación afín
- Hay dos tipos de iluminación: flat shading y Gouraud shading; con flat shading se pueden rellenar aproximadamente 2.5 veces más polígonos por segundo que con Gouraud shading
- Las texturas se aplican mediante inverse texture mapping, buscando el texel del mapa de textura para cada píxel rasterizado
- El Affine Texture Mapping de la GPU de PlayStation solo usa coordenadas 2D X/Y y descarta la profundidad, por lo que no realiza corrección de perspectiva
- No se implementó texture filtering, y para corregir escala se usa nearest neighbour, que es rápido y barato pero hace que los modelos con textura se vean en bloques
- La GPU soporta semitransparencia y dithering en triángulos, y PlayStation es descrita como especialmente destacada en esos efectos
Uso de VRAM y límites visuales
- La idea de usar gran parte de la VRAM de 1MB para el frame buffer exige reajustarse a formatos estándar de TV y reduce el espacio para texturas y tablas de color; además, la propia GPU solo puede renderizar un frame buffer de hasta 640×480 píxeles con color de 16 bits
- Un buffer de 640×480 a 16 bits deja 424KB de VRAM para recursos, pero en los televisores domésticos de la época la ventaja de mayor resolución no era especialmente evidente
- El adjustable frame-buffer evita desperdiciar VRAM en resoluciones con poco impacto perceptible, reduciendo el tamaño del frame buffer para aumentar el espacio de texturas y tablas de búsqueda de color
- El demo Gears Episode 2 de Halkun muestra una configuración que divide un frame buffer de 640×480 en dos buffers de 320×480 y usa page flipping para renderizar una escena mientras muestra la otra
- Ese layout consume solo 600KB de VRAM, y deja los 424KB restantes para tablas de búsqueda de color y texturas, formando una configuración eficiente junto con una caché de texturas de 2KB
- La VRAM puede mapear varias profundidades de color al mismo tiempo, así que junto a un frame buffer de 16bpp puede colocarse un bitmap de 24bpp, común en cuadros de FMV
- Como el rasteriser solo trabaja a nivel de píxel y no rastrea qué fracción del píxel ocupa un triángulo, pueden aparecer saltos en el contorno de los modelos y flicker o superposición en intersecciones de triángulos
- La ordering table deja en manos del desarrollador o del programa decidir qué geometría va delante; si se usan muchos cálculos aproximados por rendimiento, pueden aparecer flickering o problemas de superficies ocultas
- La transformación afín no tiene percepción de profundidad y puede producir texture warping cuando la cámara está cerca del modelo y perpendicular a la línea de visión; algunos juegos reducían la distorsión con tessellation o reemplazo por color sólido
- Los fondos pre-renderizados se usaban cuando se necesitaban escenas más realistas que lo que la GPU podía mostrar en tiempo real, colocando video transmitido por MDEC sobre dos triángulos
Audio y juegos basados en CD
- La SPU soporta 24 canales de samples ADPCM de 16 bits con calidad de Audio CD a 44.1kHz
- La SPU ofrece funciones de pitch modulation, frequency modulation, ADSR envelope, looping y digital reverb
- La Sound RAM, que funciona como búfer de audio, es una DRAM de 512KB; los juegos solo pueden usar 508KB para almacenar samples, y activar reverb reduce aún más la capacidad disponible
- El controlador de CD puede enviar samples directamente al mezclador de audio sin intervención del búfer de audio ni de la CPU, y los samples comprimidos con codificación XA pueden ser decodificados por la SPU en tiempo real
- El medio CD-ROM daba a los juegos de PS1 620MB de almacenamiento, alta calidad de audio y una velocidad de lectura relativamente rápida gracias a la unidad 2x
- Se sabe que las revisiones de PS1 lanzadas hasta 1997 tenían un láser defectuoso en la unidad de CD, lo que provocaba saltos frecuentes en FMV y Audio CD; los modelos posteriores mejoraron la unidad láser y su carcasa para aliviar el problema
E/S, BIOS y entorno de desarrollo
- Los primeros PlayStation tenían puertos de E/S Serial y Parallel para accesorios, pero fueron eliminados en revisiones posteriores por su baja adopción y por el temor a que facilitaran eludir la protección anticopia
- El subsistema de CD está compuesto por un DSP que controla motor, láser y señal RF; una Sub-CPU con microcontrolador Motorola 68HC05, 512B de RAM y 16KB de ROM; un CD Controller que intermedia entre la CPU principal y el subsistema de CD; y un búfer SRAM de 32KB
- El programa en ROM de la Sub-CPU implementa el procedimiento de protección anticopia y lo hace cumplir independientemente de la voluntad de la CPU principal
- En el frente hay 4 conectores para 2 controles y 2 Memory Card; las cuatro ranuras son eléctricamente idénticas y tienen direcciones fijadas en hardware
- El sistema almacena la BIOS en una ROM de 512KB, y la BIOS proporciona arranque, user shell y rutinas de E/S
- Como el acceso a la ROM de la BIOS es muy lento por su bus de datos de 8 bits, la API se ofrece en forma de Kernel copiado a la RAM principal durante el arranque, y 64KB de la RAM principal quedan reservados para el sistema operativo de PlayStation
- El proceso de arranque sigue el orden de ejecución de la ROM de la BIOS, carga del sistema operativo de PlayStation, visualización del splash, verificación de autenticidad del CD, comprobación y ejecución de
SYSTEM.CNFo, en su defecto, muestra del shell - El shell es una interfaz gráfica simple que permite copiar y borrar partidas guardadas de Memory Card y reproducir Audio CD
- El SDK de Sony incluía compilador de C y biblioteca, y la biblioteca se conectaba con rutinas de la BIOS para acceder al hardware
- El DTL-H2000 para estudios es una tarjeta ISA de doble ranura con el interior del PS1, circuitería de E/S y depuración, y requiere software que corre en una PC con Windows 3.1 o 95
- El Net Yaroze para aficionados incluía toolkit, manual y una consola PS1 negra, pero al no tener acceso a la unidad de CD, imponía la limitación de que todo el software homebrew debía caber en la RAM principal
Protección anticopia y bloqueo regional
- La protección anticopia de Sony funciona haciendo que la Sub-CPU compruebe si la tabla de contenidos del CD tiene un Wobble Groove grabado con una frecuencia específica
- El Wobble Groove se introduce durante el proceso de mastering, no puede copiarse con una grabadora de CD común, y la TOC está en el área Lead-In del CD, donde se repite varias veces por tolerancia a fallos
- La TOC del juego contiene una de las cadenas SCEA, SCEE o SCEI, y este método también se usa para el bloqueo regional
- Como la verificación solo se hace una vez al inicio, puede eludirse cambiando manualmente el disco justo después de la autenticación mediante el swap trick, aunque existe riesgo de dañar la unidad
- Algunos juegos intentaron bloquear el swap trick reinicializando la unidad durante el gameplay para repetir la verificación
- Un Modchip es una pequeña placa programada para imitar la señal de Wobble Groove; se soldaba a la consola, y aunque fue legalmente polémico, se volvió muy popular
- Juegos posteriores añadieron sus propias protecciones, centradas en checksums, para responder a la expansión de modchips, grabadoras de CD y emuladores
- Libcrypt de Sony combina un enfoque de hardware, que guarda checksums de sectores específicos en el subcanal del disco, con rutinas de software dentro del juego que recuperan esos checksums, los mezclan con otros valores y los validan
1 comentarios
Opiniones de Hacker News
Hay regiones de memoria que se mapean a la misma memoria física — https://psx-spx.consoledev.net/memorymap/
Cuando hicieron el port de Metal Gear Solid de PSX a PC, los programadores de Konami usaron un truco bastante agresivo para guardar si una bomba C4 estaba colocada en una pared o en el piso
Básicamente, el puntero apuntaba a la misma dirección de memoria física, pero según si estaba puesta en la pared o en el piso, creo que hacían algo como aplicar OR con
80000000ho usarA0000000h. Fue hace mucho y ya no recuerdo bien qué hicieron exactamente, pero el proceso de portearlo a PC fue divertidoHay un iterador de arreglos defectuoso en el código del BIOS que puede copiar datos arbitrarios a una posición superior en el mapa de memoria respecto al puntero base. Normalmente eso no permite sobrescribir código ejecutable porque el puntero base está muy arriba, pero por el aliasing de memoria, si ajustas bien los valores, la escritura puede “volver” y sobrescribir el BIOS
Así que, en la práctica, solo con entrar a la pantalla de la memory card puedes arrancar un BIOS personalizado y desde ahí ejecutar
PSX.EXEsin pasar la verificación del mechacon, eludiendo la protección anticopiaTambién me gustaría saber más sobre el port de MGS. Me pregunto si recuerdas algo; según recuerdo, gran parte del scripting usaba TCL, y parece que MGS 1~4 usaban lenguajes de script de la misma familia
Hace poco se filtró el código fuente de MGS2, pero probablemente estaba tan cerca de una reescritura completa que casi no debía compartir nada con la base de código de PSX
La PS1 tampoco tenía suficiente RAM para cubrir toda la ventana de decodificación de RAM, así que aparecía aliasing de RAM. No conozco bien el mecanismo, pero alguna vez vi que, aunque un ejecutable de PS1 fijaba el puntero de pila al final de los 8 MiB de RAM del kit de desarrollo, en una consola retail igual terminaba cayendo al final de los 2 MiB de RAM y funcionaba bien. En teoría, también se podrían meter bits ahí, sin tocar una región de memoria con comportamiento de caché distinto
https://github.com/FoxdieTeam/mgs_reversing/blob/master/sour...
https://en.wikipedia.org/wiki/Classic_Mac_OS_memory_manageme...
Como resultado, en algunos modelos apareció un modo de compatibilidad hacia atrás no muy distinto de la compuerta A20 de las PC, aunque duró poco tiempo
Están Arm Top Byte Ignore (TBI), Intel Linear-Address Masking (LAM) y su versión modificada Linear Address Space Separation (LASS), además de AMD Upper Address Ignore (UAI); UAI todavía no es seguro frente a ataques SLAM. Encima de eso también hay extensiones de seguridad como ARM Memory Tagging Extension (MTE)
Es un gran artículo, pero en realidad se publicó originalmente en 2019. Las discusiones anteriores fueron en 2020 https://news.ycombinator.com/item?id=22932134 y en 2021 https://news.ycombinator.com/item?id=27576902, con 114 comentarios cada una
Es un sitio web realmente hermoso. Todo está dispuesto con mucho cuidado y parece un gran ejemplo de un jardín digital bien curado. Se siente muy bien mantenido y claramente hecho por una persona
Estoy trabajando ahora mismo en un proyecto relacionado con PS1 y quería publicar este artículo antes de pronto mostrarlo
Me gustaría saber si alguien recomienda un emulador de PS1 para web/JS/WASM. En escritorio me gustaron PCSX-Redux [0] y DuckStation [1]
Encontré algunos intentos basados en JS/emscripten, pero agradecería cualquier recomendación
[0] https://github.com/grumpycoders/pcsx-redux/
[1] https://duckstation.org/
La PS1 fue una arquitectura que me hizo apreciar RISC, o más exactamente una arquitectura load-store, y me hizo darme cuenta de que yo estaba pensando mal las cosas del lado de x86
La arquitectura de la PS1 es fascinante. También muestra por qué los juegos de PS1 terminaron teniendo ese estilo tan distintivo y reconocible que todavía hoy se intenta recrear
Me gustan los artículos de Copetti. No diría que conozco bien todo lo que cubre, pero incluso solo recorrer los textos y diagramas ya es disfrutable
En especial, es divertido tratar de entender qué estaba pasando dentro de máquinas como las consolas de quinta y sexta generación
https://fabiensanglard.net/
Mejor todavía porque es un artículo de antes de Claude
Que se ejecutara la instrucción después del salto al principio parecía una locura, pero después de unos días se volvió natural. En N64 también había un problema parecido, así que había que encontrar una instrucción para meter entre dos multiplicaciones
Si la primera multiplicación terminaba en dos ciclos, por ejemplo por multiplicar por 0, y la siguiente instrucción también era una multiplicación, la CPU se detenía
Así que, si ocurría una excepción, el manejador de interrupciones del kernel tenía que revisar si la siguiente instrucción era COP2 y sumarle 4 al contador de programa para evitar ejecutarla dos veces
Además, las instrucciones COP2 no se podían poner en el branch delay slot, probablemente por una razón similar. Pero algunos juegos, si mal no recuerdo Tekken 3, de hecho hacían eso. Como varios emuladores tuvieron problemas con esta parte o necesitaron manejo especial, siempre me pregunté si era una medida oculta contra la emulación
Los artículos de esta serie siempre son excelentes
Los juegos de PS1 no han envejecido tan bien para los estándares actuales, pero si haces upscale de los juegos de PS2 a 1440p~4K, me parecen casi perfectos
Claro que hay mucha nostalgia de por medio, pero también tiene un encanto evidente, y desde que entendí las limitaciones de hardware tan particulares de PS1 me gusta cada vez más con el paso del tiempo. Con solo ver los feeds de redes sociales, los “gráficos de PS1” están viviendo una especie de renacimiento, y mucha gente intenta recrear esa estética
En cuanto a gameplay, esta consola tiene una biblioteca enorme con miles de juegos lanzados comercialmente, además de muchas joyas ocultas. Me sorprendería más encontrar a un jugador que no pudiera hallar ni un solo juego de esa lista que se ajuste a sus gustos