Entradas etiquetadas con gSMS
gSMS – Emulador de Master System en C++
1 mar
Autores: Israel López Fernández
Última versión: Final
Licencia: GNU General Public License
Plataformas: PC
Descripción:
Binarios y código fuente del Trabajo Final de Carrera de Ingeniería Técnica en Informática de Sistemas en la Universidad Politécnica de Madrid titulado Emulador de SEGA Master System en C++.
Como su nombre indica versa sobre la creación de un emulador de SEGA Master System desde cero usando el lenguaje de programación C++.
La documentación que acompaña a estos ejecutables y código fuente se proporciona en formato PDF en la sección Publicaciones.
Descargas:
gSMS – Emulador de Master System en C++ (binarios y código fuente)
Ya soy ingeniero (incluye proyecto)
1 mar
A pesar de los nervios iniciales todo fue mejor de lo esperado (me vino muy bien quedarme solo en la sala durante unos minutos hasta la llegada del tribunal para echarme unas partidas al Alex Kidd in Miracle World en el proyector) y acabó con una calificación de matrícula de honor, algo que me llena de júbilo y orgullo y me convierte oficialmente en ingeniero.

La realización de este proyecto me ha llevado 8 meses (lo empecé el 1 de Julio pasado) y mucho esfuerzo, sobretodo por ir sacándolo adelante empezando a trabajar al mes de iniciarlo, pero veo que no ha sido en vano y el tiempo invertido ha merecido la pena.
Con esto me quito un gran peso de encima, más que nada la “obligación” de tener que ponerme con ello cada vez que llegaba cansado de trabajar, por lo que ahora podré volver a disfrutar de algo más de tiempo sin este tipo de obligaciones.
Como prometí cuando lo inicié, he puesto a disposición del público tanto el documento del proyecto como el código fuente y binarios desarrollados. El documento está licenciado con una licencia Creative Commons “Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España”, mientras que el código lo está con una GNU General Public License (GPL).
Ambos pueden descargarse desde mi página web (el documento en la sección de Publicaciones y el código fuente y binarios en Proyectos) y el documento también desde el siguiente enlace de Safe Creative:
Estoy abierto a responder cualquier duda que pudiera surgir con la lectura del mismo.
Emulador de SEGA Master System en C++ (español)
1 mar
Como su nombre indica versa sobre la creación de un emulador de SEGA Master System desde cero usando el lenguaje de programación C++.
Se proporciona el documento en formato PDF tal cual fue presentado, a excepción del código fuente del mismo que ha sido extraído del documento y puesto a disposición en sus archivos correspondientes (ver emulador gSMS en la sección proyectos).
Está licenciado bajo una licencia Creative Commons “Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España”.
El VDP – Parte III
10 ago
Como ya dije, los caracteres son la mínima unidad representable y ocupan 8×8 píxeles.
Cada caracter está representado por 32 bytes de la VRAM del VDP, luego teniendo 16 KBytes de RAM es trivial que podremos representar 512 caracteres en dicha memoria. Aunque, como veremos más adelante, hay zonas de esta memoria ocupadas por otras unidades de información, al VDP eso le da igual.
De los 32 bytes de cada caracter, cada 4 de ellos se usan para representar una fila de las 8 que lo componen. El color se obtiene de los 4 planos de bits formados por estos 4 bytes.
Por ejemplo, el primer caracter (ocupa las direcciones 0 a 31 de la VRAM) estaría formado por los bytes:
FF, 00, FF, 00, 00, 00, C0, C0, 00, 00, C0, C0, 00, 00, C0, C0, 00, 00, C0, C0, 00, 00, C0, C0, 00, 00, C0, C0, 00, 00, C0, C0, 00, FF, 00 y 00.
Desglosado en sus bits sería:
Byte b7 b6 b5 b4 b3 b2 b1 b0 0 1 1 1 1 1 1 1 1 c0 FIRST PIXEL ROW:1 0 0 0 0 0 0 0 0 c1 '0101' = color #52 1 1 1 1 1 1 1 1 c23 0 0 0 0 0 0 0 0 c3 4 0 0 0 0 0 0 0 0 c0 SECOND PIXEL ROW:5 0 0 0 0 0 0 0 0 c1 '1100' = color #12,6 1 1 0 0 0 0 0 0 c2 '0000' = color #0.7 1 1 0 0 0 0 0 0 c3 8 0 0 0 0 0 0 0 0 c0 THIRD PIXEL ROW9 0 0 0 0 0 0 0 0 c110 1 1 0 0 0 0 0 0 c211 1 1 0 0 0 0 0 0 c3 12 0 0 0 0 0 0 0 0 c0 FOURTH PIXEL ROW13 0 0 0 0 0 0 0 0 c114 1 1 0 0 0 0 0 0 c215 1 1 0 0 0 0 0 0 c3 16 0 0 0 0 0 0 0 0 c0 FIFTH PIXEL ROW17 0 0 0 0 0 0 0 0 c118 1 1 0 0 0 0 0 0 c219 1 1 0 0 0 0 0 0 c3 20 0 0 0 0 0 0 0 0 c0 SIXTH PIXEL ROW21 0 0 0 0 0 0 0 0 c122 1 1 0 0 0 0 0 0 c223 1 1 0 0 0 0 0 0 c3 24 0 0 0 0 0 0 0 0 c0 SEVENTH PIXEL ROW25 0 0 0 0 0 0 0 0 c126 1 1 0 0 0 0 0 0 c227 1 1 0 0 0 0 0 0 c3 28 0 0 0 0 0 0 0 0 c0 EIGHTH PIXEL ROW29 1 1 1 1 1 1 1 1 c1 '0010' = color #230 0 0 0 0 0 0 0 0 c231 0 0 0 0 0 0 0 0 c3
Se puede observar que en este ejemplo solo se usan 4 colores, en concreto los correspondientes al índice de la paleta número 0, 2, 5 y 12. Como ya veremos estos colores pueden ser cualquiera de los soportados siempre que estén en la posición indicada dentro de la paleta.
Suponiendo que los índices se correspondieran con los siguientes colores (podría ser cualquier color, esto es un supuesto):
- 0 -> Blanco.
- 2 -> Rojo.
- 5 -> Azul.
- 12 -> Verde.
Implementando interrupciones en el Z80
24 jul
Antes de nada, os sugiero leer esta entrada donde ya comenté el funcionamiento de los modos de interrupción, tipo de interrupciones y el hardware asociado a todo esto.
Bien, si no me equivoco, en la Master System el único dispositivo que provoca interrupciones es el VDP. En concreto, genera una interrupción en dos momentos diferentes: al acabar de pintar un fotograma y al acabar de pintar una línea. Ya escribiré una entrada al respecto más adelante, pero así os hacéis una idea.
Por otro lado, según el manual de referencia de la propia SEGA, la Master System solo atiende al modo de interrupción 1 (el más sencillito de ellos), así que a menos que los programadores se salten las recomendaciones en sus juegos y establezcan otro modo sería suficiente con implementar éste (aunque yo he implementado los 3 posibles).
Respecto a las NMI, su línea está directamente conectada con el botón de Pausa de la consola, así que ese es el único momento en que se genera.
Vale, dicho esto, el Z80 tendría que tener una variable (o una función que acceda al VDP) que le diga si está activa la línea de interrupciones. Antes de ejecutar cada instrucción, si se encuentra activa la línea y están habilitadas las interrupciones (biestable IFF1=1) el procesador tratará la interrupción del modo en que se encuentre.
Concentrándonos en el modo 1 de la SMS, el Z80 salvaguardará el PC en la pila (igual que una instrucción PUSH(PC)), inhibe las interrupciones (para evitar que se encadenen) poniendo IFF1=IFF2=0 y carga el PC con el valor 0×0038.
A partir de ahí ya se seguirá ejecutando como de costumbre en la dirección 0×0038.
En cuanto a las NMI, la cosa es más sencilla, pues siempre que esté activada su línea se ejecutará la rutina, es decir, se salvaguarda el PC como en las INT, se salva IFF1 en IFF2 y se pone IFF1 a 0 y se salta a la dirección 0×0066.
Una cosa que no hice bien en su momento y tuve que rehacer hace unos días fue el tema de la línea de interrupciones, pues es el propio dispositivo que interrumpe el que debe solicitar la línea y desactivarla cuando no la necesite.
Espero que haya quedado más claro.
Jugando al Alex Kidd (entre otros)
24 jul
Por otro lado, me he puesto con el sistema de mappers de memoria para poder cargar roms de más de 32 KBytes y tengo que reconocer que ha sido un éxito relativo.
Muchos juegos que he probado se quedan en un pantallazo negro y no arrancan (¿puede que sea por no tener el sonido implementado?), pero algunos otros parece que funcionan perfectamente.
Os dejo algunos pantallazos del emulador con algunos de estos juegos funcionando, a ver si los reconocéis.



Sprites completos y bugs arreglado
23 jul
Ya he encontrado el error que mostraba sprites formados por píxeles aleatorios (como los que se ven en las capturas de ayer). Después de volverme loco revisando las interrupciones, intentando hacerme una idea del código fuente del juego a corregir mediante ingeniería inversa, comparar logs de emulación con otro emulador, etc. el fallo estaba en una máscara mal aplicada para leer de la memoria del VDP. En lugar de aplicar un 0x3FFF para devolver una dirección de entre las 65536 aplicaba un 0x3F y claro, me devolvía una entre 64… Lo que no entiendo es que no hiciera cascar el juego por todos lados…
Bueno, aparte de eso me he puesto a implementar los “efectos especiales” relativos a sprites, esto es, zooms, desplazamientos y caracteres dobles.
Aquí os paso unas capturas de mi emulador mostrando la demo “Interactive Sprite Test”.

Añadido soporte de sprites y controles
22 jul
Como digo, quería probar algún juego comercial (de momento solo los de 32 KBytes, pues es lo máximo que puede direccionar una Master System sin tener implementado el sistema de mappers), así que he aprovechado en un ratillo para implementarle los controles del jugador 1.
Los resultados de momento son satisfactorios, aunque algunos juegos no arrancan y en otros se ven fallos gráficos.
Algunos pantallazos:


Finalmente, voy a reordenar los tags del blog de modo que los avances diarios vayan en la categoría de WIP (Work in Progress) y así sea más sencillo separar la información técnica de lo implementado cada día.
Ya se muestran tiles
20 jul
Bueno, he ido corrigiendo problemas y aquí os pongo algunos pantallazos de mi emulador mostrando los tiles en varias demos:


Como se puede observar, en el pantallazo de la foto de la chica habría que aplicar un desplazamiento vertical para que saliera centrada y en la prueba de los 64 colores simultáneos hace falta aplicar interrupciones gráficas para cambiar la paleta a mitad de fotograma (sin “trucos” como ese (los conocidos como raster effects) la Master System solo es capaz de mostrar 32 colores simultáneos.
El VDP – Parte II
20 jul
Caracteres, tiles y sprites
Puede parecer al principio algo lioso, pero hay que distinguir entre tres elementos esenciales: caracteres, tiles y sprites.
Los caracteres son pequeños gráficos de 8×8 píxeles que se usarán como base para componer cualquier elemento que aparezca en pantalla (tiles y sprites). Es decir, los caracteres son la mínima unidad dibujable, no es posible dibujar un píxel solitario (habría que dibujar un caracter con 1 píxel de un color y los otros 63 de color transparente).
Los tiles, como su nombre indica, son baldosas con las que se forma el fondo de la imagen. Su particularidad es que siempre tienen una posición fija, en cada tile se dibujará un caracter y por tanto habrá 32×24 tiles visibles.
Los sprites por su parte son gráficos (también se corresponden 1:1 con un caracter) que tienen la particularidad de poder situarse en cualquier posición de la pantalla.
En la práctica, los tiles se usarán para dibujar los escenarios del juego y los sprites para dibujar los personajes, enemigos, etc. Cada tile o sprite está formado por un solo carácter.
Las paletas
El VDP de la Master System trabaja en un modo de video paletizado. Esta técnica pretende ahorrar memoria usando una serie de paletas.
En el caso concreto de la Master System el color de cada píxel viene representado por un número de 4 bits que actúa como un índice sobre la paleta. Esta paleta a su vez está formada por 32 entradas de 1 byte, cada una representando a un color de 6 bits en RGB (2 bits para cada color, de la forma xxBBGGRR).
Con este sistema paletizado podemos hacer uso de 64 colores diferentes en pantalla con solo 4 bits de información en los gráficos.
Si alguien está echando cuentas, efectivamente, con 4 bits solo puedes direccionar 16 elementos, pero la paleta tiene 32 entradas. Efectivamente, hay que establecer una división entre los 16 primeros y segundos colores. Los sprites solo pueden acceder a estos últimos mientras que los tiles pueden acceder a cualquiera de los dos bancos por medio de un bit adicional que llevan en su descripción.



