Programacion Snes - Introducción al Hardware


Buenas noches usuarios de este subforo , actualmente estoy aprendiendo a programar en ensamblador para Super Nintendo , me encontraba yo pasando a limpio unos apuntes caseros sobre este tema cuando me he dicho , ¿por que no utilizar estos apuntes y la información de las wikis para elaborar una serie de tutoriales de programación para Super Nintendo en Español? , así que me he puesto manos a la obra y he terminado de adaptar/traducir el primer capitulo del que si el tiempo me lo permite sera un tutorial sobre como programar para nuestra consola favorita , los tutoriales están hechos con la intención de ser lo mas sencillos posibles , seria recomendable que tuvierais nociones básicas
de programación pero creo que incluso una persona que no los tenga podrá seguir estos tutoriales. No esperéis algo como el tutorial de programación básico para megadrive , el ensamblador es algo mas complicado y laborioso y por lo tanto primero tendremos que aprender una serie de cosas antes siquiera de escribir nuestro primer programa. Antes de comenzar el tutorial quiero añadir dos cosas mas , una, yo estoy aprendiendo según escribo/traduzco estos tutoriales , aunque mis conocimientos ya son algo mas avanzados(que no mucho tampoco [carcajad] )así que tomaos esto con paciencia como una serie de fasciculados , cada X tiempo una entrega nueva y así hasta que consigamos hacer algo potable , realmente me gustaría hacer esto ultimo pero creo que en este año mi tiempo va a ser mas bien escaso así que puede que no acabe todos estos tutoriales pero lo intentare , si alguna vez abandono el proyecto definitivamente os lo comunicare no os preocupéis. Ahora la Segunda cosa estos tutoriales los medio traduzco , los medio redacto de esta wiki:
http://wiki.superfamicom.org/snes/show/HomePage
que por cierto es excelente si controláis de ingles no dudéis en pasarlo aunque mi objetivo es que los tutoriales sean mas sencillos aun.
concretamente este primer capitulo y los siguientes tienen su origen en este tutorial:
http://wiki.superfamicom.org/snes/show/ASM+Tutorial+Part+1
El autor del cual es Iceguy’s a quien le mando mi mas sincero agradecimiento por su trabajo , puedes colgar estos tutoriales siempre que cites el link de este hilo de eol como fuente y menciones a los autores ( en este caso traductor/adaptador Kappa64 y autor original Iceguy's) y informad-me de cualquier error en el texto de cualquier tipo para que pueda corregirlo , espero os sirva de ayuda.

Bueno después de semejante ladrillo empecemos por el principio:

Introducción al Hardware de Super Nintendo


Esto es un resumen de los componentes básicos de Super Nintendo , no pretende ni mucho menos explicarla en profundidad , si no mas bien dar una idea básica de los componentes del hardware , para empezar a programar. Si veis cualquier error por favor decídmelo.

CPU( WLA65c816)

La CPU de la Super Nintendo es un procesador WLA65c816. La CPU es la unidad de proceso central de la Super Nintendo , la cual se encarga de coordinar el funcionamiento de todos los componentes del hardware , además de las operaciones matemáticas , manipulación de la memoria , etc..

PPU's

Las PPU o Picture Processing Unit , son la parte del hardware que se encarga de “dibujar” las imágenes en pantalla y realizar efectos , como rotaciones , escalado , etc.. , la Super Nintendo cuenta con dos PPU.

--PPU1:

Generalmente se usa para dibujar los fondos de pantalla (backgrounds) y los sprites , también para rotaciones y escalar imágenes.

--PPU2:

Esta PPU se suele encargar de effectos especiales como mosaicos , ventanas , fades , etc..

Memorias RAM:

--WRAM

La WRAM es la RAM principal del sistema Tiene una capacidad de 128Kbytes(128x8 Kbits).

--VRAM 

La VRAM es utilizada para almacenar los tiles (fondos y sprites) y paletas que posteriormente la PPU1 utilizara para dibujar en la 
pantalla . Tiene una capacidad de 64Kbytes(64 x 8 kbits).

APU

APU no se refiere al famoso personaje de los Simpson( XD ) , si no a Audio Processing Unit(Unidad de proceso de Audio) . La APU se compone de varios chips y procesadores que se encargan de el sonido(Musica y Efectos Sonoros).

--SPC700(Sound CPU)

El SPC700 , se considera la CPU encargada del sonido , es una procesador con sus propios registros y su propio lenguaje ensamblador , se encarga de controlar todas las funciones de sonido de la Super Nintendo.

--S-DSP(Sound DSP)

El S-DSP cuenta con 8 canales PCM (Pulse Code Modulated) capaces de reproducir PCM en estero ,16bits y 32khz , un generador de ruido y puede realizar entre otros muchos efectos , panning y eco.

--RAM de Audio:

Es la RAM que se encarga de almacenar todos los datos referentes al sonido. La RAM tiene una capacidad de 64Kbytes , es compartida por el SPC700 y el DSP.

Esquema hardware Super Nintendo





Aprendiendo ensamblador de WLA65c816(SNES)


Capitulo 0: Preparar el entorno de desarrollo


Primero de todo debemos de preparar el conjunto de herramientas que nos permitirán trabajar , según necesitemos mas herramientas para editar gráficos/audio y demás las iré introduciendo en sus respectivos capítulos pero por ahora solo utilizaremos la herramienta esencial que todo programador necesita , el compilador . El compilador es el programa que se encargara de convertir nuestro código fuente en un archivo binario que la maquina pueda entender y ejecutar , existen varios compiladores disponibles para trabajar con Super Nintendo como SNASM, TRASM, X816 , etc pero nosotros vamos a utilizar el WLA DX.

Paso 1.-Descargando el compilador 

Podéis descargar el compilador desde este link: :

http://www.mediafire.com/?4hqa2adbcwvuhy4

Vienen incluidas tanto la versión para GNU/Linux como para Windows ya compiladas , el código fuente también esta incluido por lo que si utilizas Mac Os X seguramente puedas compilarlo , o puedas emularlo con Wine.

Paso 2.-Instalación 

GNU/Linux

1.-Descomprime el archivo y entra en la carpeta WLA_DX->Gnu-Linux ->WLA_DX_BIN selecciona el archivo wla-65816 y dale permisos de ejecución (click derecho propiedades->Permisos y selecciona la casilla de “Permitir ejecutar el archivo como un programa “) repite el mismo proceso con el archivo wlalink.

2.-Copia todos los archivos , excepto los scritps (archivos con extensión .sh) en la carpeta del sistema /usr/bin(para ello necesitaras que permisos de super usuario).

*Si no consigues copiar los archivos en /usr/bin o no quieres ensuciar la instalación de tu sistema siempre puedes copiar los archivos wla-65816 y wlalink , dentro de la carpeta de tu programa.

Windows

1.-Descomprime el archivo y entra en la carpeta WLA_DX->Windows->wla_dx_9.2->binaries 
copia todos los binarios dentro de C:\Windows\System32\

Paso 3.-Compilando

GNU/Linux

Para compilar un programa simplemente copia el script "make.sh" que encontraras en WLA_DX->Gnu-Linux ->WLA_DX_BIN dentro de la carpeta donde se encuentre el código de tu programa , a continuación ejecuta la terminal , utiliza "cd" para entrar en la carpeta donde esta el código de tu programa , seguidamente escribe "./make.sh" seguido del nombre del código fuente de tu programa( omitiendo la extensión).

*Si has optado por no copiar los binarios en /usr/bin tendrás que seguir el mismo proceso pero copiando los archivos “wla-65816” y “wlalink” dentro de la carpeta donde se encuentra el código de tu programa y utilizar este script en vez del que viene en el archivo comprimido:
http://www.mediafire.com/?lyspw3uwbwe6ntz

*Recuerda dar permisos de ejecución click derecho propiedades->Permisos y selecciona la casilla de “Permitir ejecutar el archivo como un programa “ a todos los binarios y scripts que vamos a utilizar

Windows

Copia *wla.bat en el directorio donde se encuentra el código de tu programa.
*wla.bat: http://www.mediafire.com/?59nc6t1d027fnw2

Ejecuta CMD y utiliza “cd” para acceder a la carpeta donde se encuentra tu código o busca el ejecutable de CMD(“CMD.EXE”) con el buscador de Windows y copialo en la carpeta donde se encuentra tu código y ejecutalo , después simplemente escribe en el CMD “wla” seguido del nombre del código de tu programa (omitiendo la extension).


Paso 4.-Probando a compilar una demo

Para asegurarnos de que esto a funcionado , vamos a compilar el siguiente archivo:
http://www.mediafire.com/?7pfklxa51sxxffv
*No es mas que la demo hecho por bazz’s(wiki.superfamicom.org) con un sprite diferente.

GNU/Linux

1.-Descomprimimos el archivo 

2.-Copiamos el archivo make.sh (si has optado por la otra manera copia tambien los binarios de wla) , le damos permisos de ejecución a todo , y abrimos la terminal.

3.-Entramos en la carpeta con "cd":
SELECCIONARCOPIARcd "ruta de la carpeta"

4.-Compilamos escribiendo "./make.sh" seguido del nombre del codigo fuente del programa , en este caso:
SELECCIONARCOPIAR./make.sh sprite


nos debería devolver algo así:

4.-Ahora en la misma carpeta tendrás el archivo sprite.smc , ábrelo con un emulador o pruebalo en tu Super Nintendo y disfruta de tu recompensa.

Windows:
1.-Descomprimimos el archivo 

2.-Copiamos el archivo wla.bat.

3.-Copiamos el archivo cmd.exe en la carpeta y lo ejecutamos o bien ejecutamos cmd desde el lanzador de programas y entramos en la carpeta donde tenemos el código del programa:
SELECCIONARCOPIARCD "código del programa"


4.-Escribimos "wla" seguido del nombre del archivo que contiene el código del programa:

nos debería devolver algo así:

4.-Ahora en la misma carpeta tendrás el archivo sprite.smc , ábrelo con un emulador o pruebalo en tu Super Nintendo y disfruta de tu recompensa.

Capitulo 1: Carga y almacenamiento.


La primera cosa que debes aprender son los opcodes. Un opcode es la parte del código que sirve para indicarle a la Super Nintendo que tiene que hacer , podría compararse a una sentencia en un lenguaje de programación moderno o un comando en un interprete de comandos(CMD , Bash , etc..).

Primero vamos a aprender sobre el Acumulador.El acumulador es un lugar donde cargar y descargar datos , puedes pensar en el como un banco donde almacenas y retiras pequeñas cantidades de dinero. Los dos primeros opcodes que vamos a aprender son LDA y STA , los cuales te serán indispensables cuando escribas tu código para super nintendo.

LDA(Load to Accumulator):

LDA se utiliza para cargar un valor hexadecimal , decimal o una dirección RAM en el Acumulador , su uso no es muy complicado , para cargar un valor decimal simplemente escribe "LDA" seguido de "#" y después el valor que quieres cargar. Ejemplos: 
SELECCIONARCOPIARLDA #20 ;Cargamos el valor decimal 20 en el acumulador
LDA #70 ;Cargamos el valor decimal 70 en el acumulador


*Nota:El acumulador no reconoce dígitos impares así que por ejemplo si queremos cargar el valor decimal 4 en el acumulador tendríamos que escribirlo como "04" para que sus dígitos sean pares.

Si en vez de cargar un valor decimal queremos utilizar un valor hexadecimal tendremos que añadir un símbolo del dólar "$ " delante del sostenido "# " y detrás del valor a cargar , ejemplo: 
SELECCIONARCOPIARLDA #$20 ; Cargamos el valor hexadecimal 20 que se corresponde con el numero 32 en binario , al acumulador.


STA (Set to address):

"STA" coge el valor que tiene el acumulador y lo almacena en la dirección de la memoria RAM que tu especifiques. Su uso es parecido al de "LDA" , simplemente escribes el nombre del opcode "STA " , seguido del símbolo del dólar "$ " y la dirección de memoria en al que quieres almacenar el valor actual del acumulador , ejemplo: 
SELECCIONARCOPIARSTA $18 ; Cargamos el valor del acumulador en la dirección de memoria 18(en hexadecimal).


Pongamos ahora un ejemplo practico : En la dirección de memoria $19 se almacenan el estado de Mario , si $19 vale 0 significa un estado normal , si vale 1 significa que ha comido una seta , si vale 2 ha comido una flor de fuego . si vale 3 ha tocado una estrella y es invencible. La dirección $19 actualmente vale 0 , por lo que Mario esta en un estado normal , queremos que pase al estado de flor de fuego el cual vale 2 , como lo hacemos? Simplemente cargamos el 2 en el acumulador y seguidamente lo enviamos a la dirección de memoria que guarda el valor del estado de Mario la dirección $19 , escrito en ensamblador seria: 

SELECCIONARCOPIARLTA #02; Cargamos el 2 en el acumulador.
STA $19; Almacenamos el valor del acumulador (en este momento 2) en la dirección de memoria 19(19 en hexadecimal);


STZ(Set to zero):

STZ pone a cero la dirección de memoria que se le indique , ejemplo: 
SELECCIONARCOPIARSTZ $19 ; ahora el valor de $19 es 0.


Resumen:

LDA(Load to Accumulator): Carga un valor en el acumulador

STA(Set to address): Almacena el valor actual del acumulador en una dirección de memoria.

STZ(Set to zero): Pone a 0 una dirección de memoria

#$ -> Valor hexadecimal
# ->Valor decimal
#% ->Valor binario
$ ->Dirección de memoria

Capitulo 2: Datos Técnicos(Direcciones de memoria )


2.1.- modos de direccionamiento

Existen 3 maneras para Cargar/Almacenar direcciones de memoria:

1.-Directa:



Puedes cargar un valor de 2 dígitos(xx) , esto se llama asignación directa y es una dirección
de 8 bits.

2.-Absoluta:


Puedes cargar un valor de 4 dígitos , esto se llama asignación absoluta(absolute adressing) y es una dirección de 16 bits

3.-Dirección larga(long addressing):
SELECCIONARCOPIARLDA $xxxxxx


Puedes cargar un valor de 6 dígitos , esto se llama asignación larga y es una dirección de 24 bits
*Importante: no puedes poner a cero una dirección de 24 bits(dirección larga) por que el ensamblador/compilador lo leerá como un opcode diferente , tendrás que hacer lo siguiente:
SELECCIONARCOPIARLDA #$00
STA $xxxxxx


2.2.-Organización de la memoria y bancos de datos

Direcciones de Memoria:
SELECCIONARCOPIAR$0000 - $1FFF →  RAM
$2000 - $7FFF →  Registros de Hardware
$8000 - $FFFF →  ROM


*Los bancos comprenden entre la dirección $0000 hasta la dirección $FFFF , a partir de esta dirección comienza el siguiente banco de memoria. Ejemplo:
SELECCIONARCOPIAR$010000 -> Banco 1
$01FFFF -> Fin del Banco 1
$020000 -> Banco 2
$02FFFF ->Fin del Banco 2



-RAM:

Es la memoria Ram de la Super Nintendo donde podemos almacenar y cargar datos con los cuales vamos a trabajar , como por ejemplo variables.

-ROM:

Los datos de la ROM , los datos del cartucho.
*No se pueden modificar , como su nombre indica(Read Only Memory).

-Registros de Hardware:

Son direcciones de Memoria que podemos leer y escribir , y cuyos valores sirven para configurar o controlar el hardware.

Como acceder a direcciones de memoria en diferentes bancos de datos?

Utilizando direcciones largas de 24bits (long adressing) , ya que en los primeros 2 dígitos podremos especificar el banco de datos.
Ejemplo:

Queremos leer una dirección de memoria en el banco $7E , la dirección de memoria $C100 , pero no nos encontramos en ese banco en este momento.

Esto estaría mal:

Tendriamos que hacer esto en su lugar:
SELECCIONARCOPIARLDA $7EC100
socram8888 está baneado por "incumplimiento términos y condiciones de uso"
SNES + ensamblador = [burla3]

Fuera bromas, creo que has empezado demasiado fuerte. Deberias explicar primero la arquitectura de la consola, que es ensamblador, que es un registro, que es un mapa de memoria y cual es, etc...

Y como consejo personal: para iniciarse con ensamblador, empezad con 68000 que es muchisimo mas simple y amigable (en apenas 30 minutos aprendi a manejar las instrucciones principales)
SHARE

Oscar perez

Arquitecto especialista en gestion de proyectos si necesitas desarrollar algun proyecto en Bogota contactame en el 3006825874 o visita mi pagina en www.arquitectobogota.tk

  • Image
  • Image
  • Image
  • Image
  • Image
    Blogger Comment
    Facebook Comment

0 comentarios:

Publicar un comentario