Arquitectura Game Boy Advance

Un análisis práctico por Rodrigo Copetti

Traducido por varios autores

Esto es una traducción voluntaria del artículo original. Si encuentra algún error, por favor ayude a mejorarla. ¡Gracias!

Si utiliza herramientas de accesibilidad o algún navegador antiguo, cambie a la edición "clásica".




Imágenes de apoyo

Modelo

Image
La Game Boy Advance original.
Lanzada el 21/03/2001 en Japón, el 11/06/2001 en América y el 22/06/2001 en Europa.

Motherboard

Image
Motherboard
Mostrando la revisión "03". Tenga en cuenta que "AGB" es el identificador del modelo Game Boy Advance.
La ranura para cartuchos y el amplificador de audio están en la parte posterior.
Image
Motherboard con partes importantes etiquetadas

Diagrama

Image
Diagrama de arquitectura
Cada bus de datos está etiquetado con su ancho.
El diseño mostrado del cartucho AGB no incluye un mapeador (ya que la nueva CPU es capaz de direccionar mucha más memoria), aunque los juegos con una ROM grande pueden seguir incluyendo uno.

Una introducción rápida

El diseño interno de la Game Boy Advance es bastante impresionante para tratarse de una consola portátil que funciona con dos pilas AA.

Esta consola continuará utilizando la GPU distintiva de Nintendo. Además, introducirá una CPU relativamente nueva de una empresa británica que ganará popularidad en los próximos años.


CPU

La mayoría de los componentes se combinan en un único paquete denominado CPU AGB. Este paquete contiene dos CPU completamente diferentes:

Tenga en cuenta que ambas CPU nunca funcionarán al mismo tiempo ni realizarán ningún co-procesamiento extravagante. La única razón para incluir el muy antiguo Sharp es para la retrocompatibilidad.

Dicho esto, antes de describir el chip ARM, me parece útil empezar con la historia que hay detrás de esta marca de CPU.

El milagro de Cambridge

La historia de los orígenes de la CPU ARM y su posterior ascenso a la fama es fascinante. Aquí encontramos una combinación de inversión pública, crecimiento exponencial, decisiones desacertadas y asociaciones de largo recorrido.

El auge de Acorn Computers

Image
Foto del BBC Micro con una caja de discos de 5¼ encima [1], el primer disco es Elite.

A finales de los años 70, Reino Unido se vio marcado por el inicio de una transición de una economía intervencionista a un mercado libre. En medio de esta tormenta, iniciativas con sede en Cambridge como Acorn Computers, junto con Sinclair y otros similares, estaban vendiendo kits de ordenador a laboratorios y aficionados. De manera similar a las empresas estadounidenses y japonesas, los ordenadores de Acorn dependían de la CPU 6502 y un dialecto propietario de BASIC.

Al entrar en los años 80, los intereses ministeriales dentro del nuevo gobierno británico llevaron a la creación de un proyecto para mejorar la alfabetización en informática en las escuelas [2]. Gracias al próximo ‘Proton’ de Acorn, la empresa obtuvo el contrato para construir un ordenador asequible que cumpliera con la visión del gobierno. El resultado fue el BBC Micro (apodado el ‘Beeb’), que disfrutó de un éxito significativo entre escuelas, profesores y estudiantes. Dentro del Micro, Acorn incorporó una interfaz vanguardista ‘Tube’ que podía ampliar el ordenador con un segundo procesador. Esto allanaría el camino para la próxima gran inversión de Acorn.

Durante el desarrollo de su próximo producto, esta vez enfocado a empresas, Acorn no encontró una CPU adecuada para suceder a la 6502. La presión por innovar contra la competencia japonesa y estadounidense, combinada con una planificación desafortunada, colocó a Acorn en una situación financiera complicada. Por lo tanto, se encargó a una nueva división de Acorn la producción de una CPU convincente. Para sortear las restricciones recientes de Acorn, el equipo de CPU basó su arquitectura en las enseñanzas de un artículo de investigación llamado The Case for the Reduced Instruction Set Computer [3] y su prototipo, el CPU RISC [4]. Finalmente, en 1985, Acorn entregó la CPU ARM1 como un módulo Tube para el BBC Micro, pero solo se comercializó para fines de I+D. No será hasta 1987, con la introducción del primer ordenador Acorn Archimedes, que los chips ARM (para entonces, la CPU ARM2) tomarían un papel central.

Una nueva empresa de CPU

Image
Un modelo tardío del Newton… después de jugar con él.

Durante la comercialización del Acorn Archimedes, Apple se sintió cautivada por las CPUs energéticamente eficientes de Acorn, pero la empresa estadounidense aún no estaba convencida de que la última ARM3 de Acorn fuera adecuada para el nuevo proyecto estrella de Apple, el Newton. Sin embargo, en lugar de alejarse (después de todo, Acorn era un competidor), ambos discutieron la posibilidad de evolucionar la ARM3 para cumplir los requisitos de Apple [5], a saber, frecuencia de reloj flexible, MMU integrada y direccionamiento completo de 32 bits.

Esta colaboración pronto se convirtió en una asociación donde Acorn, Apple y VLSI (fabricante de chips ARM) crearon una nueva empresa dedicada exclusivamente al desarrollo de CPUs ARM. Apple proporcionó la inversión (obteniendo el 43% de la participación), Acorn compartió su personal y VLSI se encargó de la fabricación. En 1990, Advanced RISC Machines (ARM) Ltd surgió con Robin Saxby como su presidente ejecutivo.

Años después, Apple finalmente lanzó el Newton MessagePad con un ARM610, uno de la siguiente generación de chips ARM que incorporaban las aportaciones de Apple. Mientras tanto, Acorn también lanzó el RiscPC utilizando las nuevas CPUs.

Ahora, mientras Acorn y Apple se demoraban en el mercado de ordenadores/dispositivos portátiles, ARM ideó un modelo de negocio radical. Manteniéndose al margen de la fabricación, la visión de Saxby consistía en licenciar la propiedad intelectual de ARM, en forma de diseños de CPU y su conjunto de instrucciones [6]. Esto otorgó a ARM clientes más allá del ámbito de los ordenadores, como Texas Instruments [7], que más tarde conectó a la empresa con el emergente mercado móvil (culminando en el Nokia 6110) y las cajas decodificadoras. Los años siguientes verán la tecnología de ARM incorporada en miles de millones de dispositivos móviles [8].

La asociación con Nintendo

De vuelta en Japón, y gracias al análisis de Game Boy, aprendimos que la estrategia de hardware de Nintendo para sistemas portátiles favorece un modelo de System On a Chip (SoC). Esto ha permitido a la compañía ofuscar tecnología asequible de uso común y combinarla con desarrollos internos. Al hacerlo, la nueva consola podría ser única y competitiva.

Image
CPU AGB, que alberga la CPU ARM7TDMI (entre otros muchos componentes).

Afortunadamente, el modelo de licencias de ARM se ajustaba perfectamente a esas necesidades. Ambas empresas mantuvieron conversaciones desde 1994 (un año antes del lanzamiento del Virtual Boy) a pesar de que no se materializó nada hasta muchos años después [9]. La razón era simple: los japoneses encontraron inviable la densidad de código de ARM y la necesidad de 32 cables de datos (algo que la CPU del Virtual Boy ya había logrado evitar). No obstante, el nuevo diseñador de CPU de ARM - Dave Jaggar - respondió rápidamente con el ARM7TDMI, una nueva CPU que se centró en maximizar el rendimiento bajo restricciones de energía y almacenamiento. Este fue un punto de inflexión para ARM, ya que este nuevo producto no solo complació a Nintendo, sino que también llamó la atención de Texas Instruments, Nokia y el resto de los competidores en el ámbito de los teléfonos móviles.

No es sorprendente que, cuando Nintendo comenzó a trabajar en el sucesor del Game Boy Color, su elección de CPU se convirtió en el ARM7TDMI.

El ARM7TDMI

Vamos ahora a profundizar en lo que ofrece este chip.

Manejar la CPU

Para empezar, la ARM7TDMI implementa el conjunto de instrucciones ARMv4, el sucesor del ARMv3. Esto implica:

El paquete

Ahora que sabemos cómo los desarrolladores se comunican con este chip, vamos a ver qué hay dentro del silicio.

El núcleo

En términos de circuitería, el ARM7TDMI es una versión reducida del ARM710 con adiciones interesantes. El núcleo incluye [11] [12]:

  • 16 registros de propósito general de 32 bits: Aunque es un gran avance en comparación con los siete registros de 8 bits del SM83/Game Boy, esto es un compromiso con las directrices de RISC, que requerían treinta y dos registros de 32 bits en su lugar. Esto se debe a que ARM favoreció mantener un tamaño de silicio pequeño [13].
  • Bus de datos y ALU de 32 bits: significa que puede mover y operar valores de 32 bits sin consumir ciclos adicionales.
  • Direccionamiento limpio de 32 bits: Esto es parte de la aportación de Apple. Los tres primeros CPUs ARM usaban direcciones de memoria de 26 bits para optimizar el rendimiento (el Contador de Programa y el Registro de Estado combinados podían caber en una sola palabra de 32 bits) a cambio de capacidad de direccionamiento de memoria (se podía acceder hasta 64 MB de memoria). La serie ARM6 de seguimiento (con su ISA ARMv3) implementó lógica de direccionamiento de 32 bits, pero mantuvo un modo compatible hacia atrás para el código antiguo. Ahora, el ARM7TDMI (enfocado en la movilidad) desechó el modo de 26 bits y solo alberga lógica para direcciones de 32 bits (reduciendo la cantidad de silicio necesario).
  • Sin Unidad de Gestión de Memoria (MMU): Desde el ARM1, ARM proporcionó una solución MMU. Primero como el coprocesador ‘MEMC’, y luego integrado con el ARM610. Ahora, el ARM7TDMI parece ser el único en su serie que no proporciona ninguno, potencialmente debido a la falta de interés (los primeros dispositivos móviles no requerían memoria virtual sofisticada).
  • Sin caché: Otro recorte de costes de este chip, ya que los chips ARM anteriores incluían algo de caché.

Finalmente, todo esto puede operar con una fuente de alimentación de 3 voltios [14]. Esto es un evidente paso hacia la computación móvil, ya que los núcleos anteriores requerían una fuente de 5 V.

La canalización

Desde su primera iteración, ARM ha implementado una canalización en tres etapas para ejecutar código. En otras palabras, la ejecución de las instrucciones se divide en tres pasos o etapas. La CPU busca, decodifica y ejecuta hasta tres instrucciones simultáneamente. Esto permite aprovechar al máximo los recursos de la CPU (lo que reduce el silicio inactivo) al mismo tiempo que aumenta el número de instrucciones ejecutadas por unidad de tiempo.

Al igual que dos contemporáneos muy similares, las CPUs ARM son susceptibles a peligros de datos. Sin embargo, ni el programador ni el compilador lo notarán ya que, en este caso, la CPU detendrá automáticamente la canalización cada vez que sea necesario.

También están presentes los peligros de control, pero ARM los abordó con un enfoque eficiente llamado anulación condicional: Cada vez que una instrucción de rama está en la segunda etapa (Decodificación), la CPU calculará la condición de la rama [15]. Basado en el resultado, si la rama debe ejecutarse, la CPU anulará automáticamente la instrucción de seguimiento (convirtiéndola en un relleno). Ahora, esto puede parecer ineficiente en comparación con el enfoque de MIPS (ya que un compilador MIPS puede insertar instrucciones útiles, no solo rellenos). Por lo tanto, aparte de la bifurcación, ARM proporciona ejecución condicional. Esta última convierte este diseño de canalización en una ventaja, ya que ARM puede decodificar una instrucción y calcular su condición incorporada en la misma etapa. Por lo tanto, en este caso, no se añadirán rellenos. Es por eso que la ejecución condicional es preferida sobre la bifurcación al programar para CPUs ARM [16].

Exprimir el rendimiento

Una de las desventajas de una arquitectura de carga-almacenamiento llevó a que el código de ARM fuera muy disperso. Competidores como x86 podían realizar las mismas tareas usando menores cantidades de código, requiriendo menos almacenamiento. En consecuencia, cuando Nintendo echó un vistazo al último diseño de ARM, el ARM7, no quedaron satisfechos con él. El tamaño de las instrucciones de ARM significaba que supuestos artilugios equipados con buses de 16 bits con memoria y almacenamiento limitados - todo para ahorrar costos y energía - harían que la CPU fuera ineficiente y congestionada. Afortunadamente, Dave Jaggar acababa de terminar de diseñar el ARM7 y no se rendiría todavía. Durante su viaje tras reunirse con Nintendo, se le ocurrió una solución: El conjunto de instrucciones Thumb [17].

Thumb es un subconjunto del conjunto de instrucciones ARM cuyas instrucciones están codificadas en palabras de 16 bits (en lugar de 32 bits) [18]. Al ser de 16 bits, las instrucciones Thumb requieren la mitad del ancho de bus y ocupan la mitad de la memoria.

El principal compromiso es que Thumb no ofrece ejecución condicional, dependiendo en su lugar de las bifurcaciones. Además, sus códigos de operación de procesamiento de datos solo usan un formato de dos direcciones, en lugar de uno de tres direcciones, y solo tiene acceso a la mitad inferior del archivo de registros (por lo tanto, solo hay disponibles ocho registros de propósito general). En general, dado que las instrucciones Thumb solo ofrecen un subconjunto funcional de ARM, los desarrolladores pueden tener que escribir más instrucciones para conseguir el mismo efecto.

En la práctica, Thumb utiliza el 70% del espacio del código ARM. Para memoria de 16 bits de ancho, Thumb ejecuta más rápido que ARM. Si es necesario, las instrucciones ARM y Thumb pueden mezclarse en el mismo programa (lo que se denomina interfuncionamiento) para que los desarrolladores puedan elegir cuándo y dónde utilizar cada modo.

Los extras

El ARM7TDMI es, en esencia, un núcleo compatible con ARMv3 con extras. A este último se hace referencia en su nombre (TDMI), lo que significa:

  • TThumb: la inclusión del conjunto de instrucciones Thumb.
  • DExtensiones de depuración: proporcionan depuración JTAG.
  • MMultiplicador mejorado: los núcleos ARM anteriores necesitaban varios ciclos para calcular multiplicaciones completas de 32 bits, esta mejora los reduce a unos pocos.
  • IMacrocélula EmbeddedICE: habilita puntos de interrupción de hardware, puntos de vigilancia y permite detener el sistema mientras se depura código. Esto facilita el desarrollo de programas para esta CPU.

En conjunto, esto convierte al ARM7TDMI en una solución atractiva para dispositivos móviles e integrados.

Áreas de memoria

La inclusión de Thumb en particular tuvo una fuerte influencia en el diseño final de esta consola. Nintendo mezcló buses de 16 y 32 bits entre sus distintos módulos para reducir costes, al tiempo que proporcionaba a los programadores los recursos necesarios para optimizar su código.

Image
Arquitectura de memoria del sistema.

La memoria utilizable de la Game Boy Advance se distribuye en las siguientes ubicaciones (ordenadas de más rápida a más lenta) [19]:

Aunque esta consola se comercializó como un sistema de 32 bits, la mayor parte de su memoria sólo es accesible a través de un bus de 16 bits, lo que significa que los juegos utilizarán mayoritariamente el conjunto de instrucciones Thumb para evitar gastar dos ciclos por búsqueda de instrucción. Sólo en circunstancias muy excepcionales (por ejemplo, necesidad de utilizar instrucciones que no se encuentran en Thumb y almacenarlas en IWRAM), los programadores se beneficiarán del conjunto de instrucciones ARM.

Convirtiéndose en una Game Boy Color

Aparte de la inclusión de hardware GBC (Sharp SM83, BIOS original, modos de audio y vídeo, ranura para cartuchos compatibles, etc.), hay dos funciones adicionales necesarias para que funcione la retrocompatibilidad.

Desde el punto de vista del hardware, la consola se basa en interruptores para detectar si hay un cartucho de Game Boy o Game Boy Color insertado. Un detector de forma en la ranura del cartucho identifica eficazmente el tipo de cartucho y permite a la CPU leer su estado. Se supone que algún componente de la CPU AGB lee ese valor y desconecta automáticamente el hardware que no se necesita en modo GBC.

Desde el lado del software, hay un registro especial de 16 bits llamado REG_DISPCNT que puede alterar muchas propiedades de la pantalla, pero uno de sus bits pone la consola en ‘modo GBC’ [21]. Al principio, me costó entender exactamente cuando la GBA intenta actualizar este registro. Por suerte, algunos desarrolladores ayudaron a aclararlo:

Creo que lo que ocurre durante el arranque GBC es que comprueba el interruptor (legible en REG_WAITCNT 0x4000204), hace el fundido (un fundido muy rápido, difícil de notar), y finalmente cambia a modo GBC (la BIOS escribe en REG_DISPCNT 0x4000000), parando el ARM7.

La única pieza que falta en el rompecabezas es qué pasaría si quitaras una parte de la carcasa del cartucho GBC para que el interruptor dejara de estar pulsado, y luego hicieras un cambio de modo por software al modo GBC. El modo multi-arranque podría ayudar en este caso. No estoy seguro de si es necesario pulsar el interruptor para que el bus de cartuchos de la GBC funcione correctamente, o si simplemente funciona. Estoy dispuesto a suponer que el interruptor es necesario para que el bus funcione, pero es sólo una suposición.

Dan Weiss (alias Dwedit, actual responsable de PocketNES y Goomba Color)


Gráficos

Antes de comenzar, notarás que el sistema es una mezcla entre SNES y Game Boy, el núcleo gráfico sigue siendo el conocido motor 2D llamado PPU. Recomiendo leer esos artículos antes de continuar, ya que voy a revisar muchos conceptos explicados previamente.

En comparación con las anteriores Game Boy, ahora tenemos una pantalla LCD que puede mostrar hasta 32.768 colores (15 bits). Tiene una resolución de 240 x 160 píxeles y una frecuencia de actualización de ~60 Hz.

Organizando el contenido

Image
Arquitectura de memoria de la PPU.

Los gráficos se distribuyen a través estas regiones de memoria:

Construyendo el frame

Si has leído los artículos anteriores, la GBA te resultará familiar, aunque hay funciones adicionales que pueden sorprenderte, y no olvides que esta consola funciona con dos pilas AA.

Voy a tomar prestados los gráficos del Sonic Advance 3 de Sega para mostrar cómo se compone un fotograma.

Mosaicos

Image
Estos dos bloques están formados por mosaicos de 4 bpp.
Image
Puede que notes algunos patrones verticales extraños aquí, estos no son gráficos sino “Mapas de Mosaicos” (ver siguiente sección).
Image
Estos dos bloques están reservados para los sprites.
Pares de bloques de cuadros encontrados en la VRAM.

Los mosaicos de GBA son estrictamente mapas de bits de 8x8 píxeles, pueden usar 16 colores (4 bpp) o 256 colores (8 bpp). Los mosaicos de 4 bpp consumen 32 bytes, mientras que los de 8 bpp consumen 64 bytes.

Los mosaicos pueden almacenarse en cualquier lugar de la VRAM, sin embargo, la PPU los quiere agrupados en bloques de cuadros: Una región de 16 KB. Cada bloque está reservado para un tipo específico de capa (fondo y sprites) y los programadores deciden dónde empieza cada bloque de cuadros. Esto puede dar lugar a cierto solapamiento que, como consecuencia, permite que dos bloques de cuadros compartan los mismos mosaicos.

Debido al tamaño de un bloque de cuadros, se pueden almacenar hasta 256 mosaicos de 8 bpp o 512 mosaicos de 4 bpp por bloque. Se permiten hasta seis bloques de cuadros, que combinados requieren 96 KB de memoria: exactamente la cantidad de VRAM que tiene esta consola.

Sólo se pueden utilizar cuatro bloques de cuadros para fondos y dos para sprites.

Fondos

Image
Capa de fondo 0 (BG0).
Image
Capa de fondo 2 (BG2).
Image
Capa de fondo 3 (BG3).
Esta capa en particular se desplazará horizontalmente en determinadas líneas de exploración para simular efectos de agua.
Capas de fondo estático en uso.

La capa de fondo de este sistema ha mejorado notablemente desde la Game Boy Color. Por fin incluye algunas características encontradas en la Super Nintendo (¿recuerdas las transformaciones afines?).

La PPU puede dibujar hasta cuatro capas de fondo. Las capacidades de cada uno dependerán del modo de funcionamiento seleccionado [22]:

  • Modo 0: proporciona cuatro capas estáticas.
  • Modo 1: solo hay tres capas disponibles, aunque una de ellas es afín (puede girarse y/o escalarse).
  • Modo 2: suministra dos capas afines.

Cada capa tiene una dimensión de hasta 512x512 píxeles. Si es una afín, entonces será de hasta 1024x1024 píxeles.

El dato que define la capa de fondo se llama Mapa de mosaicos. Para implementar esto de forma que la PPU lo entienda, los programadores utilizan bloques de pantalla, una estructura que define porciones de la capa de fondo (mosaicos de 32x32). Un bloque de pantalla ocupa sólo 2 KB, pero se necesitará más de uno para construir toda la capa. Los programadores pueden colocarlos en cualquier lugar dentro de los bloques de cuadros de fondo, ¡esto significa que no todas las entradas de las fichas contendrán gráficos!

Sprites

Image
Capa de sprite renderizada

El tamaño de un sprite puede ser de hasta 64x64 píxeles de ancho, pero para tener una pantalla tan pequeña acabarán ocupando una gran parte de ella.

¡Por si fuera poco, ahora la PPU puede aplicar transformaciones afines a los sprites!

Las entradas del sprite tienen un ancho de 32 bits y sus valores pueden dividirse en dos grupos:

  • Atributos: contiene posición x/y, volteo h/v, tamaño, forma (cuadrado o rectángulo), tipo de sprite (afín o regular) y ubicación del primer tile.
  • Datos afines: Solo se utilizan si el sprite es afín. Especifican la escala y la rotación.

Resultado

Image
Todas las capas combinadas (Tachán).

Como siempre, la PPU combinará todas las capas automáticamente, ¡pero aún no ha terminado! El sistema dispone de un par de efectos para aplicar sobre estas capas:

  • Mosaico: consigue hacer que los tiles parezcan más en bloque.
  • Fusión alfa: combina los colores de dos capas superpuestas dando lugar a efectos de transparencia.
  • Ventanas: divide la pantalla en dos ventanas diferentes donde cada una puede tener sus propios gráficos y efectos independientes, la zona exterior de ambas ventanas también se puede renderizar con tiles.

Por otro lado, para actualizar el fotograma hay múltiples opciones disponibles:

  • Órdenes de la CPU: el procesador tiene ahora acceso completo a la VRAM siempre que quiera. Sin embargo, puede producir artefactos no deseados si altera algunos datos a mitad de fotograma, por lo que esperar a VBlank/HBlank (manera tradicional) sigue siendo la opción más segura en la mayoría de los casos.
  • Empleo del Controlador DMA: el DMA proporciona tasas de transferencia ~10x más rápidas y puede programarse durante VBlank y HBlank. Esta consola proporciona 4 canales DMA (dos reservados para sonido, uno para operaciones críticas y otro para propósito general). Tenga en cuenta que el controlador detendrá la CPU durante la operación (¡aunque es posible que apenas lo note!).

Más allá de los mosaicos

A veces es posible que queramos componer un fondo a partir del cual el motor de mosaicos no pueda dibujar todos los gráficos necesarios. Ahora, las consolas modernas solucionaron esto implementando una arquitectura de búfer de fotogramas, pero esto no es posible cuando hay muy poca RAM… Pues bien, resulta que la GBA tiene 96 KB de VRAM que son suficientes para asignar un mapa de bits con las dimensiones de nuestra pantalla LCD.

La buena noticia es que la PPU realmente implementó esta funcionalidad incluyendo tres modos extra, estos se llaman modos de mapa de bits [23]:

La razón de tener dos mapas de bits es permitir pasar de página: dibujar sobre un mapa de bits previamente mostrado puede exponer algunos artefactos extraños durante el proceso. Si en su lugar manipulamos otro, entonces ninguno de los fallos se mostrará al usuario. Una vez finalizado el segundo mapa de bits, la PPU puede actualizarse para que apunte al segundo, intercambiando efectivamente el fotograma visualizado.

Image
Super Monkey Ball Jr. (2002).
El modo Bitmap permitía a la CPU proporcionar algunos gráficos 3D rudimentarios para los escenarios.
Los objetos de primer plano son sprites (capa separada).
Image
Tonc’s demo.
Mapa de bits renderizada con algunas primitivas.
Observa que la pantalla no muestra patrones significativos producidos por los motores de mosaicos.
Image
Nickelodeon’s SpongeBob SquarePants.
Episodio distribuido como un cartucho de GBA Video (sufrió mucha compresión, claro).
Ejemplos de programas que utilizan modos de mapa de bits.

En general, parece una característica de vanguardia, sin embargo, la mayoría de los juegos se aferraron al motor de mosaicos. ¿Y por qué? Porque en la práctica consume muchos recursos a la CPU.

La CPU puede delegar la mayor parte de los cálculos en el chip gráfico. En cambio, el sistema de búfer de fotogramas que proporciona la PPU se limita a mostrar ese segmento de memoria como una única capa de fondo, lo que significa que se acabaron las transformaciones afines individuales, la superposición de capas o los efectos a menos que la CPU los compute. Además, el búfer de fotogramas ocupa 80 KB de memoria, por lo que sólo 16 KB (la mitad) están disponibles para almacenar mosaicos de sprites.

Por esta razón, estos modos se usan excepcionalmente, como para reproducir vídeos en movimiento (Game Boy Advance Video dependía completamente de esto) o renderizar geometría 3D con la CPU. En cualquier caso, los resultados fueron, como mínimo, impresionantes.


Audio

La GBA incorpora un reproductor de muestras de 2 canales que funciona en combinación con el sistema de sonido heredado de la Game Boy.

Funcionalidad

Aquí tienes un desglose de cada componente de audio utilizando en Sonic Advance 2 como ejemplo:

PCM

Canales exclusivos de PCM.

El nuevo sistema de sonido ahora puede reproducir muestras PCM, proporciona dos canales llamados Sonido Directo donde recibe muestras utilizando una cola FIFO (implementada como un búfer de 16 bytes).

Las muestras son de 8 bits y con signo (codificadas en valores de -128 a 127). La frecuencia de muestreo por defecto es de 32 kHz, aunque esto depende de cada juego: como una frecuencia mayor implica un mayor tamaño y más ciclos de CPU, no todos los juegos gastarán la misma cantidad de recursos para alimentar el chip de audio.

El DMA es esencial para evitar atascos en los ciclos de la CPU. Los temporizadores también están disponibles para mantener el sincronismo con la cola.

PSG

Canales exclusivos de PSG.

Aunque el subsistema de la Game Boy no comparte su CPU, sí da acceso a su PSG. Por razones de compatibilidad, se trata del mismo diseño que el de la Game Boy original. Anteriormente he escrito este artículo que entra en detalle sobre cada canal en particular.

La mayoría de los juegos de GBA lo utilizaban como acompañamiento o efecto. Los posteriores optimizarán su música para PCM y dejarán el PSG sin utilizar.

Combinado

¡Tachán!

Por último, todo se mezcla automáticamente y se emite a través del jack de altavoces/auriculares.

Aunque la GBA sólo tiene dos canales PCM, algunos juegos pueden reproducir mágicamente más de dos muestras simultáneas. ¿Cómo es esto posible? Bueno, aunque sólo tener dos canales puede parecer un poco débil sobre el papel, la CPU principal puede utilizar algunos de sus ciclos para proporcionar tanto la secuenciación de audio como la mezcla [24] (¡eso debería darte una idea de lo potente que es el ARM7!). Además, en la sección “Sistema operativo”, ¡descubrirás que la ROM de la BIOS incluía un secuenciador de audio!

Lo mejor de ambos mundos

Algunos juegos llevaban la dualidad PCM-PSG más allá y “alternaban” el chip protagonista en función del contexto.

En este juego (Mother 3), el jugador puede ingresar a dos habitaciones diferentes, una relativamente normal y otra con una configuración nostálgica. Dependiendo de la habitación en la que se encuentre el personaje, la misma partitura sonará en estilo moderno o en estilo 8 bits.

Habitación normal, sólo utiliza PCM.
Habitación nostálgica, el PSG lidera la sintonía.

Sistema Operativo

El vector de reinicio de ARM7 está en 0x00000000, que apunta a la ROM de 16 KB de la BIOS. Esto significa que la Game Boy Advance arranca primero desde la BIOS, que a su vez muestra la icónica pantalla de inicio y luego decide si cargar el juego o no.

Image
Animación de inicio a mitad de camino.
Image
Animación de inicio al final.
La GBA cuenta con una nueva animación de inicio en la que ahora muestra su paleta de colores extendida y capacidades de escala de sprites.

La ROM de la BIOS también almacena rutinas de software que los juegos pueden llamar para simplificar ciertas operaciones y reducir el tamaño del cartucho [25]. Entre ellas figuran:

La BIOS está conectada a través de un bus de 32 bits y se implementa utilizando una combinación de instrucciones ARM y Thumb, aunque esta última es la más destacada.

Además, recuerda que todo esto sólo funcionará en el ARM7. En otras palabras, no hay ninguna aceleración de hardware disponible para acelerar estas operaciones. De ahí que Nintendo proporcionara toda esta funcionalidad a través de software.


Juegos

Los juegos se distribuyen en un nuevo formato de cartucho propietario, sigue llamándose Game Pak, pero presenta un diseño más pequeño.

Image
El nuevo diseño del Game Pak para juegos de GBA [26].

Los programas de GBA se escriben principalmente en C con secciones de rendimiento crítico en ensamblador (ARM y Thumb) para ahorrar ciclos. Nintendo suministró un SDK con bibliotecas y compiladores.

La programación para la GBA compartió algunas metodologías con la Super Nintendo, pero también heredó todos los avances de principios de la década de los 2000: lenguajes de alto nivel estandarizados, compiladores fiables, CPUs RISC depurables, estaciones de trabajo no propietarias para el desarrollo, documentación comparativamente mejor y… ¡acceso a Internet!

Acceso a los datos del cartucho

Aunque el ARM7 tiene un bus de direcciones de 32 bits, hay solo 24 líneas de dirección conectadas al cartucho.

Esto significa, en teoría, que se puede acceder a hasta 16 MB en el cartucho sin necesidad de un mapeador. Sin embargo, el mapa de memoria muestra que 32 MB de datos del cartucho son accesibles. Entonces, ¿qué está pasando aquí? La verdad es que la Game Pak utiliza direcciones de 25 bits (lo que explica ese bloque de 32 MB) pero su bit más inferior está fijado a cero. Por lo tanto, únicamente los 24 bits restantes son manipulados. Así funciona el direccionamiento del Game Pak.

Image
Representación del modelo de direccionamiento del Game Pak. Fíjate en cómo el último bit de la dirección de 25 bits (llamado ‘A0’) siempre es cero. También debo señalar que en realidad, las patillas de direcciones y datos están compartidas/multiplexadas.

Ahora bien, ¿significa esto que los datos situados en direcciones impares (con su bit menos significativo a 1) serán inaccesibles? No, porque el bus de datos es de 16 bits: en cada transferencia, la CPU/DMA obtendrá el byte localizado más el siguiente, lo que le permitirá leer tanto direcciones pares como impares. Como puede ver, se trata de otra obra de ingeniería que aprovecha al máximo las capacidades del hardware al tiempo que reduce los costes.

Curiosamente, las CPUs ARM de 26 bits también recurrían a la misma técnica. Estos albergaban un Contador de Programa de 24 bits, ya que los bits tenían que ser múltiplos de ocho (también conocido como alineados por palabra) por lo que los dos últimos bits de la dirección de 26 bits siempre eran ceros. Sin embargo, dado que estas CPUs recuperan 32 bits (el primer byte más los siguientes tres), se puede acceder a todo el espacio de direcciones de 26 bits.

Memoria RAM del cartucho

Para guardar partidas, los Game Pak podrían incluir [27]:

Accesorios

Se incluye el mismo conector Game Boy Link para proporcionar capacidades multijugador o contenido adicional. Sin embargo, ya no hay sensor de infrarrojos, por alguna razón (tal vez demasiado poco fiable para grandes transferencias).

Image
El cable de conexión GameCube-Game Boy Advance [28], este se conecta al puerto del controlador de la GameCube (manejado por la Interfaz Serial) para transferencias de datos.

Además, la BIOS de la GBA implementaba internamente una función especial conocida como Multi-boot: Otra consola (ya sea GBA o GameCube) puede enviar un juego funcional a la EWRAM del receptor y entonces, este último arrancaría desde allí (en lugar del Game Pak).


Anti-Piratería y Homebrew

En términos generales, el uso de cartuchos propietarios supuso una gran barrera en comparación con el constante juego del gato y el ratón al que tuvieron que enfrentarse otros fabricantes de consolas al utilizar el CD-ROM.

Para luchar contra los cartuchos bootleg (reproducciones no autorizadas), la BIOS de la GBA incorporaba las mismas comprobaciones de arranque que se encontraban en la Game Boy original.

Flashcarts

A medida que el almacenamiento en estado sólido se hacía más asequible, aparecía en el mercado un nuevo tipo de cartucho. Los flashcarts parecían cartuchos normales pero tenían el añadido de una memoria regrabable o una ranura para tarjetas. Esto permitía a los usuarios reproducir archivos ROM de juegos dentro de la consola. En realidad, el concepto no es nuevo: los desarrolladores han utilizado internamente herramientas similares para probar sus juegos en una consola real (y los fabricantes proporcionaban el hardware necesario para ello).

Las soluciones anteriores incluían una memoria NOR Flash grabable (hasta 32 MB) y algunas SRAM respaldadas por baterías. Para cargar los binarios en el cartucho, el cartucho se suministraba con un cable Link-to-USB que se utilizaba con una GBA y un PC con Windows XP. Mediante el uso de software de flasheo y controladores patentados, el ordenador cargaba un programa de arranque múltiple en la GBA, que a su vez se utilizaba para transferir un binario de juego del PC al flashcart (insertado en la GBA). En general, toda la tarea de subir un juego se consideró demasiado lenta. Los Flashcarts posteriores (como el ‘EZ-Flash’) ofrecían mayor almacenamiento y la posibilidad de ser programados sin necesidad de la GBA como intermediario [29]. Los últimos se basaban en almacenamiento extraíble (SD, MiniSD, MicroSD o lo que fuera).

La disponibilidad comercial de estas tarjetas resultó ser un área legal gris: Nintendo condenó su uso por permitir la piratería, mientras que algunos usuarios defendieron que era el único método para ejecutar Homebrew (programas realizados fuera de los estudios de juegos y, en consecuencia, sin la aprobación de Nintendo). El argumento de Nintendo se apoyaba en el hecho de que los flashers como el EZ-Writer ayudaban a los usuarios a parchear las ROM de los juegos para que pudieran ejecutarse en los cartuchos EZ-Flash sin problemas. Tras los intentos legales de Nintendo, estos cartuchos fueron prohibidos en algunos países (como el Reino Unido). No obstante, persistieron en todo el mundo.


Esto es todo amigos

Image
Mi GBA y un par de juegos.
¡Lástima que no tenga retroiluminación!

Contribuir

Este artículo forma parte de la serie de Arquitectura de consolas. Si te ha resultado interesante, por favor considere donar. Tu contribución se usará para tener mas herramientas y recursos que ayudarán a mejorar la calidad de los actuales artículos y próximos.

Donate with PayPal
Become a Patreon

También puedes comprar la edición eBook en inglés. Trato las ganancias como donaciones.

Image

Esta es la lista de herramientas adquiridas o interesantes a adquirir:

### Interesting hardware to get (ordered by priority)

- Any Dev kit (only if found at a reasonable price)

### Acquired tools used

- Original GBA (£40)
- The two games analysed in the article (£20)

De alternativa, puedes ayudar sugiriendo cambios y/o agregando traducciones.


Copyright and permissions

This work is licensed under a Creative Commons Attribution 4.0 International License. You may use it for your work at no cost, even for commercial purposes. But you have to respect the license and reference the article properly. Please take a look at the following guidelines and permissions:

Article information and referencing

For any referencing style, you can use the following information:

For instance, to use with BibTeX:

@misc{copetti-gba,
    url = {https://www.copetti.org/writings/consoles/game-boy-advance/},
    title = {Game Boy Advance Architecture - A Practical Analysis},
    author = {Rodrigo Copetti},
    year = {2019}
}

or a IEEE style citation:

[1]R. Copetti, "Game Boy Advance Architecture - A Practical Analysis", Copetti.org, 2019. [Online]. Available: https://www.copetti.org/writings/consoles/game-boy-advance/. [Accessed: day- month- year].
Special use in multimedia (Youtube, Twitch, etc)

I only ask that you at least state the author’s name, the title of the article and the URL of the article, using any style of choice.

You don’t have to include all the information in the same place if it’s not feasible. For instance, if you use the article’s imagery in a Youtube video, you may state either the author’s name or URL of the article at the bottom of the image, and then include the complete reference in the video description. In other words, for any resource used from this website, let your viewers know where it originates from.

This is a very nice example because the channel shows this website directly and their viewers know where to find it. In fact, I was so impressed with their content and commentary that I gave them an interview 🙂.

Appreciated additions

If this article has significantly contributed to your work, I would appreciate it if you could dedicate an acknowledgement section, just like I do with the people and communities that helped me.

This is of course optional and beyond the requirements of the CC license, but I think it’s a nice detail that makes us, the random authors on the net, feel part of something bigger.

Third-party publishing

If you are interested in publishing this article on a third-party website, please get in touch.

If you have translated an article and wish to publish it on a third-party website, I tend to be open about it, but please contact me first.


Fuentes / Sigue leyendo

Anti-Piratería

Audio

CPU

Juegos

Gráficos

Sistema Operativo

Fotografía


Rodrigo Copetti

Rodrigo Copetti

Espero que hayas disfrutado este artículo, si quieres saber más sobre el autor entra aquí y si quieres ayudarlo entra aquí

rsslinkedintwittergithub facebookreddit