Beruflich Dokumente
Kultur Dokumente
De la emulacin
de mquinas recreativas
Introduccin
Durante los aos ochenta el sector del videojuego
profesional vivi su poca dorada. Era un tiempo en
que los sistemas domsticos eran muy inferiores a los
sistemas especializados que ofrecan los salones
recreativos. Los xitos se sucedan para las compaas
desarrolladoras que integraban en su plantilla
ingenieros electrnicos y de programacin para
confeccionar a medida cada nuevo ttulo. Las empresas
que hoy son punta de lanza en el sector del videojuego
domstico comenzaron su andadura diseando estos
completos sistemas donde se cuidaban desde los
aspectos electrnicos de circuitos integrados
especficos para cada juego, hasta el prosaico mueble
de madera.
En 1987 haba en las casas ordenadores Spectrum, Amstrad, Commodore, Dragn... todos
ellos con un ancho de bus de un octeto y frecuencias de reloj en torno a 4 MHz. Las
mquinas que poblaban los salones recreativos portaban, por lo general, los mismos
procesadores que los ordenadores domsticos; sin embargo llevaban muchsima
circuitera adicional especializada en sonido y vdeo. La distancia tcnica era enorme,
el precio tambin: Una placa de vdeo profesional costaba unas 150 000 pesetas (unos
1000) cuando un ordenador completo, compuesto por monitor, placa, teclado y lectora
de cintas costaba unas 50000 Ptas. (unos 300). Al precio de la placa de vdeo haba que
aadir el del mueble, monitor y fuente de alimentacin. Las partidas solan pagarse a
25 Ptas. (unos 15 cntimos), el mismo juego poda comprarse para ordenador por unas
875 Ptas. (poco ms de 5); el precio de 35 partidas. La diferencia, sin embargo, entre la
versin original, de recreativa y la conversin a ordenador era abismal.
En las imgenes vemos la primera fase de Gryzor (Konami, 1987) en sus versiones de
mquina recreativa y de ordenador. Pese a la obvia superioridad de la mquina, estas
imgenes no descubren todos los mbitos de stas: El juego original ofreca un suave
desplazamiento de fondos, con dos planos distintos para aportar sensacin de
profundidad; la versin domstica presentaba una sucesin de pantallas fijas, sin
movimiento. El original ofreca msica y efectos sonoros simultneamente; en el
ordenador, haba que elegir entre uno u otro, estando disponible la msica slo para
los poseedores del equipo de gama alta: CPC 6128 (128 koct de memoria en vez de 64)
Objetivos
Este proyecto de final de carrera pretende documentar con gran detalle el
funcionamiento de los sistemas recreativos de vdeo especialmente en cuanto sistemas
electrnicos aunque tambin se comentarn aspectos mecnicos y comerciales de los
mismos. La labor de documentacin persigue el mantenimiento y conservacin del
patrimonio tcnico que estos equipos constituyen como parte de la historia de la
electrnica. Ahora que ya parecen llegar a su ocaso, las mquinas recreativas
constituyen un conjunto cerrado y coherente cuya evolucin es menester que sea
escrita y guardada.
Mas para dotar a este trabajo de mayor vala tcnica, nos proponemos utilizar todos los
datos descritos a lo largo del presente documento para elaborar varios programas
emuladores- que simularn el entorno electrnico etolgicamente1 y harn posible que
el cdigo mquina original que antao estaba grabado en memorias ROM se ejecute en
nuestros modernos ordenadores de manera fidedigna, siendo, por tanto, facsmiles de
las mquinas verdaderas. El desarrollo de estos emuladores implica aunar dotes de
ingeniera inversa y directa , de electrnica y de informtica, de induccin y de
deduccin; constituyendo, por tanto, una labor cuya realizacin satisface enormemente
al ingeniero que encuentra en ella la resolucin de problemas de naturaleza lgica y la
ordenacin de lo hallado en pro de la construccin de un nuevo ingenio.
Resumidamente los objetivos son:
De etologa estudio del comportamiento. Hemos preferido este cultismo frente al barbarismo
behavioural.
1 parte
Los sistemas de las mquinas recreativas de vdeo
Las mquinas recreativas de vdeo son sistemas electrnicos especializados en proporcionar una
partida a un videojuego a cambio de un pago previo. El caso ms habitual es la mquina de
diseo a medida: una placa, unas palancas y botones, un armario y en ocasiones hasta una
fuente de alimentacin especficas para el juego en s y que no sirven para ningn otro.
La mquina recreativa se compone de un mueble de madera, donde se montan las
dems partes; de luces, que iluminan el espacio en torno al equipo; de unas palancas y
botones, para accionar el juego; de un monedero y cofre, que filtra las monedas que
entran y las almacena; de una placa de circuito impreso, donde est el juego en s; de
altavoces, para la msica y efectos sonoros; y de una fuente de alimentacin que
proporciona potencia elctrica a todo lo dems: luces, monedero y placa (los altavoces
y las palancas se alimentan desde la placa)
Midway/Namco, 1982
10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Ya en la mitad inferior del armario, sobre una repisa se colocan las palancas y los botones. La
calidad de estos suele ser muy elevada, pese a lo cual no son irrompibles y solan acabar
sucumbiendo ante la furia de jugadores insatisfechos. Los botones y la palanca no son ms que
interruptores que llevan su seal por un cable cada uno (sin ninguna multiplexacin) hasta la
placa, que es adems quin suministra la tensin elctrica necesaria para su funcionamiento.
La placa puede colocarse verticalmente en uno de los laterales de la mquina o en
horizontal sobre unas baldas disponibles al efecto. La placa tiene por lo general un
conector normalizado llamado jamma, al que llega la manguera de cables
provenientes de altavoces, tubo, palancas, monitor y fuente.
La alimentacin est colocada al fondo del mueble y es la nica conexin con el
exterior. Suele proveer de +5V y +12V, el primero para la lgica digital y el segundo
RGB, rojo verde y azul; hace referencia a que la seal llega al monitor separada por tres
canales y no en forma de crominancia y luminancia como en un televisor
3
11
Canal
1
Pulsos
1
N de monedas
1
12
1
1
4
20
1
1
Canal
1
1
1
Pulsos
1
2
10
N de monedas
2
1
1
13
El monitor
El monitor de las mquinas recreativas funcionaba con una frecuencia horizontal de 15
kHz y una vertical de 60 Hz. La manera de conectarlo a la placa y al mueble se describe
en otros apartados, en ste vamos a ocuparnos de valernos de un televisor como
monitor.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
1 lnea de comunicaciones
masa del rojo
masa de las comunicaciones
rojo
blanco
masa del vdeo compuesto
masa del blanco
salida de vdeo compuesto
entrada de vdeo compuesto
masa comn (carcasa del conector)
14
nmero de la patilla
15
11
7
5,9,13,18 y 21
20
16
15
La placa
La placa contiene el videojuego en s, la descripcin de los circuitos que la componen se
realizar ms adelante; en este apartado nos ocuparemos de la interconexin de sta
con el resto del sistema.
posicin de la placa en el
mueble normal
16
conexionado de Gryzor
Como se indica en la imagen superior, todas las entradas son activas a nivel bajo y no
existe ninguna multiplexacin de las seales; aunque esto eleva el nmero de cables
simplifica la circuitera de las palancas a la mnima expresin posible: un interruptor;
facilitando, por tanto, las reparaciones posteriores.
17
Estos datos suelen codificarse en un solo dgito cada uno salvo la paleta que
habitualmente ocupa entre dos y cuatro dgitos. El asociar una paleta cambiable a los
grficos permite efectos como el de la famosa cascada, cuya agua no se mueve sino que
sus colores ciclan; es decir, lo nico que el procesador toca son los dgitos que indican
con que paleta se pinta el bloque, el efecto ocurre por s mismo.
El optimismo reside en no contar el tiempo invertido en descontar la variable que formara el
bucle y en realizar el salto al final de cada iteracin
18
La operacin de dibujar una imagen es costosa, sin embargo, una vez dibujada no ha
terminado el trabajo: es necesario desplazarla. El escenario sobre el que se juega es
esencialmente mvil, ha de avanzar cuando el personaje avanza, puesto que si fuese al
contrario (un escenario inmvil y un personaje ambulante) el jugador acabara
rebasando los lmites de la pantalla obligando a un cambio brusco de fondo; esta
situacin siempre trata de evitarse. Lo habitual es que el jugador ocupe siempre una
situacin prxima al centro del monitor y que sea el fondo el que refleje los
movimientos del personaje.
Desplazar la imagen costara tanto como volver a pintarla si fuese el procesador el
encargado de hacer el trabajo. Habra que tomar cada punto del fondo y repintarlo en
otras coordenadas, la labor para un procesador de 8 dgitos es inmensa.
Los circuitos grficos tienen unos registros en los que se indica el desplace de la
imagen en coordenadas. De esta forma si se desea mover el fondo cinco puntos a la
izquierda bastar con almacenar un cinco (o menos cinco) en el registro de desplace
horizontal, dem para los casos verticales.
Si pintamos todo desplazado cinco puntos a la izquierda estaremos empezando cinco
puntos ms tarde a pintar y estaremos acabando cinco puntos despus: de dnde
salen esos puntos adicionales a la derecha? La solucin viene de trabajar con una
pantalla virtual habitualmente cuatro veces mayor que la real, de forma que lo que se
nos presenta no es ms que una ventana dentro de un espacio mayor. La esquina
superior de esa ventana por la que nos asomamos al fondo constituyen los registros de
desplace mencionados.
19
Las mquinas que llegaron a partir de 1986 comenzaron a incluir varios planos de
fondo en lugar de uno slo, para dar as profundidad a la imagen. La tcnica consiste
en colocar debajo del fondo que hemos estudiado otro de idnticas caractersticas, pero
que se desplazar a una velocidad inferior. Se trata de imitar las lneas de fuga que
tienen las imgenes reales tridimensionales. Cuando vamos en un tren y miramos por
la ventanilla, los postes de la catenaria pasan raudos ante nosotros, pero las distantes
montaas se desplazan con lentitud, entre nuestra posicin y el horizonte cada punto
parece moverse a una velocidad.
Incluir dos planos de fondo se convirti pronto en una necesidad, sin embargo los
juegos con ms de dos planos fueron pocos, aunque hay casos donde se lleg a incluir
ms de una decena de planos, a veces formados por finas bandas horizontales para
mostrar nubes o montaas lejanas, el caso ms renombrado fue el juego Shadow of
the Beast.
Aadir un segundo plano es ms una sobrecarga para la memoria que para el
procesador, pero en ambos casos supone poco esfuerzo adicional. Al ser un plano ms
lento no es necesario actualizar los bloques que lo componen de forma tan frecuente y
generalmente se permite que la animacin sea cclica de manera que la montaa o nube
que sale por un lado de la pantalla aparece por el opuesto. El tiempo de proceso
requerido es escaso y la memoria tambin ha de serlo, puesto que la variedad de
imgenes a almacenar es considerablemente menor.
Desde el punto de vista de la circuitera s que se aade una complicacin considerable.
El dibujado del fondo ha de hacerse ahora en paralelo, duplicando la circuitera y
utilizando una puerta lgica al final que dejar pasar el punto del segundo plano slo
cuando el del primero sea cero.
20
Los bloques son en general de 16x16 puntos, pero eso no implica un problema a la hora
de dibujar objetos mayores, ya que puede pintarse un bloque junto a otro para
componer objetos mayores. En ocasiones la misma circuitera grfica dispone de
aceleracin para este caso, por ejemplo, en la mquina Gryzor hay un dgito asociado a
los objetos que indica si habr de pintarse el siguiente objeto almacenado en la ROM
grfica justo debajo del objeto pintado.
El nmero mximo de objetos dibujables depende de la circuitera grfica, siendo lo
habitual una cifra entre 16 y 64. Como habitualmente slo se trabaja con un pequeo
nmero de objetos muy inferior a las capacidades de la circuitera, las estructuras de
los objetos inutilizados se rellenan de forma que sus coordenadas de dibujado indican
la esquina inferior derecha de la pantalla, por lo que se pintarn fuera del rea visible
por el jugador.
21
Introito histrico
Los circuitos que vamos a estudiar surgen de la necesidad de tener sonido a bajo coste
en sistemas donde la msica no es el objetivo principal. Ejemplos de aparatos que
cumplen este requisito son:
Los ordenadores personales: aunque en ocasiones escuchamos msica en ellos, no es su
principal funcin; por tanto, son candidatos a soluciones de bajo coste.
Las mquinas recreativas tipo A y B: En este grupo se incluyen las denominadas
tragaperras, los pitufos8 y las mquinas de videojuegos. En todas ellas, la msica, los
sonidos o las voces son elementos importantes para atraer al cliente; pero no la funcin
primordial9
Telfonos: hoy da se usan en telefona mvil, aunque no es un modelo basado en MF
sino en MIC10 por lo general.
Electrodomsticos y juguetes electrnicos.
La problemtica en estos aparatos es conseguir una calidad de sonido aceptable a un
coste pequeo (orientativamente, menor del 5% del costo total). Las primeras
soluciones, en los albores de la electrnica integrada, fue digitalizar el sonido para
reproducirlo posteriormente. El inconveniente es el tamao de las memorias ROM
necesarias; para solventarlo se recurra (all por 1980) a bajas frecuencias de muestreo y
codificaciones de alta relacin seal-ruido, como la modulacin diferencial y
adaptativa de pulsos codificados (ADPCM). Esto se traduce en baja calidad, mxime
hace veinte aos, cuando el precio de una ROM de 4kB era prohibitivo.
El remedio pasa por generar la msica sobre la marcha11, a travs de un sistema que a
modo de instrumentista, reproduce adecuadamente la composicin. De esta forma la
informacin a guardar sera slo de notas y tiempo, mucho menor que antao. Aunque
ahora es necesario un director, un procesador que indicase qu nota tocar en cada
Son mquinas destinadas a los nios de menor edad. En general son algn tipo de mvil sobre
el que el nio se sienta. Al insertar el dinero ste se mover y producir sonidos.
9 La funcin primordial de estos ejemplos sera, respectivamente: el premio aleatorio, el
movimiento mecnico y el juego en s.
10 Modulacin de Impulsos Codificados, bsicamente son trenes de pulsos de frecuencia
programable
11 En el mercado de los videojuegos se habla de cuatro generaciones: la primera se basaba en
grficos, sonido y comportamiento predeterminados; la segunda generacin incluy el sonido
desarrollado en tiempo real (usando sintetizadores); la tercera la vivimos en la actualidad,
donde los grficos del videojuego tambin se calculan conforme se necesitan sin dibujarse
previamente; la cuarta pretende que el comportamiento de las entelequias (enemigos, etc...) del
juego tambin se calculen sobre la marcha, es decir, busca un comportamiento ms inteligente
de los rivales.
8
22
Tenemos una ltima forma de modificar la seal: envolverla. Hay muchos tipos de
ventana14, es decir: funciones con las que multiplicamos la seal. La ms comn en
estos circuitos es la mostrada en la figura inferior; se trata de una trapezoide que
introduce el sonido y ms tarde lo atena. Su utilidad es evidente; permite introducir
las notas con suavidad y apagarlas con naturalidad.
Aunque este enfoque puede parecer a priori ineficaz por su excesiva sencillez, la
realidad es que estamos rodeados de l, en formas incluso ms simplificadas (sin
envolvente); es el tpico pitido electrnico. Si bien ha sido la base sonora de sistemas
antiguamente tan potentes como el Atari ST15.
23
24
Bloques de un sintetizador FM
El sintetizador FM es notablemente ms complejo que el MIC, huelga decir que una
modulacin en frecuencia es ya de por s conceptualmente mucho ms complicada que
una seal MIC.
Los operadores
El subsistema fundamental dentro un sintetizador de MF es el operador. Un operador es
un circuito electrnico digital que genera una seal binaria representacin de una
forma de onda peridica programable, generada internamente, relacionada
matemticamente con la seal presente a su entrada.
La combinacin de operadores permite conseguir seales discretas complicadas, el
parecido de estas secuencias a lo que se obtendra digitalizando el sonido de un
instrumento musical es lo que dotar una meloda de realismo. El objetivo se cifra
entonces en la semejanza de dos seales temporales o de dos espectros; si bien el
resultado debe ser evaluado auditivamente, por lo que secuencias diferentes a las
reales pueden ser vlidas en ciertos contextos.
Funciones posibles
Un operador responde en general a la siguiente expresin:
0.8
0.8
0.6
0.6
0.4
0.4
0.2
0.2
-0.2
-0.2
-0.4
-0.4
-0.6
-0.6
-0.8
-0.8
-1
200
400
600
800
1000
1200
1400
1600
-1
200
400
1
0.8
0.6
0.6
0.4
0.4
0.2
0.2
-0.2
-0.2
-0.4
-0.4
-0.6
-0.6
-0.8
-0.8
0
200
400
600
800
1000
1200
Fig. 3 B(t) = 1
1400
1600
800
1000
1200
1400
1600
1400
1600
Fig.2 B(t)=0.5
0.8
-1
600
-1
200
400
600
800
1000
1200
Fig. 4 B(t)=1.5
25
0.8
0.8
0.6
0.6
0.4
0.4
0.2
0.2
-0.2
-0.2
-0.4
-0.4
-0.6
-0.6
-0.8
-0.8
-1
200
400
600
800
1000
1200
1400
1600
-1
200
Fig. 5 B(t) = 2
Fig. 6
1
0.8
0.8
0.6
0.6
0.4
0.4
0.2
0.2
-0.2
-0.2
-0.4
-0.4
-0.6
-0.6
-0.8
-0.8
-1
200
Fig. 7
400
600
800
1000
1200
1400
N c + Dc
= 0.5; B(t ) = 1.0
N m + Dm
1600
-1
200
Fig. 8
400
600
800
1000
1200
1400
1600
N c + Dc
= 0.5; B(t ) = 0.5
N m + Dm
400
600
800
1000
1200
1400
1600
N c + Dc
= 0.5; B(t ) = 1.5
N m + Dm
N c + Dc
determina dnde va a ser ms influyente la
N m + Dm
26
TA
TD1 TD2 TR
27
16
17
28
R0
R1
R2
R3
R4
R5
R7
R8
R9
RA
RB
RC
RD
RE
RF
B7
B6
B5
B4
B3
B2
B1
Ajuste de tono fino con 8-dgitos
Frecuencia del canal A
Sin usar
Ajuste grueso, 4 dgitos
Ajuste de tono fino con 8-dgitos
Frecuencia del canal B
Sin usar
Ajuste grueso, 4 dgitos
Ajuste de tono fino con 8-dgitos
Frecuencia del canal C
Sin usar
Ajuste grueso, 4 dgitos
Mezclador y puertos de E/S
Ruido
Tono
E/S
ES/B ES/A C
B
A
CB
A
Sin
M
L3
L2
L1
L0
Volumen del canal A
usar
Volumen del canal B
Sin usar
M
L3
L2
L1
L0
Volumen del canal C
Sin usar
M
L3
L2
L1
L0
Frecuencia
de
la Ajuste grueso de 8-dgitos
envolvente
Ajuste fino de 8-dgitos
Forma de la envolvente
Sin usar
CONT ATT ALT
HOLD
Puerto de E/S de datos A 8-dgitos de datos
Puerto de E/S de datos B 8-dgitos de datos
Como vemos, la simple descripcin es ya bastante intuitiva. Cabe explicar las distintas
formas de envolvente admitidas:
B3
CONT
0
0
1
1
1
1
1
1
1
1
B2
ATT
0
1
0
0
0
0
1
1
1
1
B1
ALT
X
X
0
0
1
1
0
0
1
1
B0
HOLD
X
X
0
1
0
1
0
1
0
1
29
El YM-2203
El YM-2203 representa la transicin entre los sintetizadores basados en MIC y los
puramente de FM Vemos como pese a introducir la nueva tecnologa de FM la
compatibilidad con los circuitos existentes basados en MIC se consider bsica en su
diseo.
Caractersticas
18
30
ruido y las ondas cuadradas. En cuanto al volumen puede ser fijo o determinado
por diez envolventes distintas. Existe un convertidor D/A por cada sonido.
Puerto de control de Entrada / salida
Son de nuevo dos puertos de propsito general de Entrada / salida
Temporizador
Se proveen dos tipos de temporizadores.
Modelo de programacin
$00 ~
Frecuencia de las ondas senoidales.
$05
$06 Frecuencia de la fuente de ruido.
$07 Control de los puertos de E/S.
$08 ~
Volumen. Puede ser fijo (por CPU) o variable (por el generador de envolvente)
$0A
$0B ~
Controla el ciclo de envolvente en el sistema de volumen variable
$0C
$0D Especifica la forma de la envolvente.
$0E ~
Dos puertos de 8-dgitos de propsito general
$0F
$21 Informacin de prueba, siempre vale 0
$24 ~
Tiempo de disparo de los temporizadores A y B
$26
$27 Controla la operacin de los temporizadores.
$2D
Especifica por cuanto se divide la seal de reloj de entrada.
~ $2F
$30 ~
Controla la relacin entre el tono principal y el primer armnico.
$3E
$40 ~
Controla el nivel total. Es el ndice de modulacin para la envolvente.
$4E
$50 ~
Controles de clave y escala. Control del tiempo de ataque de la envolvente.
$5E
$60 ~
Tiempo de cada de la envolvente.
$6E
$70 ~
Tasa de mantenimiento de la envolvente.
$7E
$80 ~
Nivel de mantenimiento de la envolvente.
$8E
$90 ~
Generacin del patrn de la envolvente.
$9E
$A0
Nmero de frecuencia de cada canal
~
$A6
31
El mapa de registros ocupa 256 octetos; y sirve para configurar los circuitos que
producen el sonido. Vamos a ver qu significan algunos de estos registros.
B: WRITE BUSY FLAG (Slo lectura). Por primera vez aparece un elemento de
sincronizacin. Cuando sea necesario escribir continuamente en el integrado hay que
consultar este dgito y comprobar que sea cero antes de continuar.
KON: KEY ON Activa la salida de un canal.
Generador de fase: Utiliza la combinacin de los siguientes valores:
KC: KEY CODE( Octava, nota) Se guarda la nota en 7-dgitos, tres para la octava y
cuatro para la nota.
KF: KEY FRACTION Compuesto por 6-dgitos permite separar la informacin de fase
dividiendo el intervalo de nota
MUL: PHASE MULTIPLY Sirve como factor que multiplica a KC y KF
DT1 (DETUNE 1) Se utiliza para desemparejar la informacin de fase con la de
frecuencia.
DT2 (DETUNE 2) Idntico al interior. Cuando se desincroniza fase y frecuencia se
producen efectos sonoros tiles.
32
f noise (kHz ) =
M (kHz )
donde M = 3579.545kHz Y puede variar entre 3.5 kHz hasta
32 * NFRQ
111.9 kHz
LFO: Low Frequency OSC Provee de sonido a la modulacin de frecuencia y de
amplitud.
LFRQ: LOW FREQUENCY Se fija la frecuencia de oscilacin con 8-dgitos
W: WAVE FORM Se elige entre ocho formas de onda, variantes de seales en rampa,
triangulares, cuadradas y ruido.
PMD/MAD: PHASE MODULATION DEPTH/AMPLITUDE MODULATION DEPTH:
Representa los ndices de modulacin.
Temporizadores El circuito dispone de dos temporizadores programables, uno de 10dgitos y otro de 8-dgitos. Provocan una interrupcin cuando su cuenta ha terminado.
33
34
Bloques fundamentales
Una mquina de videojuegos se compone bsicamente de un sistema de proceso, un
sistema de vdeo y un sistema de entrada de datos:
Bloques fundamentales
y el sistema de vdeo:
35
36
37
38
39
Los cuentamonedas
b
cuentamonedas
Los cuentamonedas son los que llevan la caja, es decir, la contabilidad del juego. Cada
vez que la mquina acepta una moneda ha de enviar una seal a estos para que
contabilicen la partida. La forma de hacerlo en Gryzor es a travs de un registro LS174
que sigue los cambios de las seales provenientes del monedero y de un circuito
propio, el 005924 que ataca a los cuentamonedas (externos a la placa)
40
El oscilador
Oscilador a 24MHz
El procesador principal
41
En Gryzor hay dos circuitos grficos 007121, que posibilitan la existencia de dos fondos
simultneos en la imagen. Slo hemos mostrado una parte de estos en la figura puesto
que se trata de integrados inmensos con ms de 200 conexiones. En la placa ocupan un
tamao notable por lo que seguramente, debajo del encapsulado cermico se
encuentren no uno sino varios circuitos integrados.
Hemos querido destacar en la imagen el hecho de que estos circuitos se conectaban a
memorias ROM (donde estaban los dibujos) y a memorias RAM (donde se pintaba la
pantalla)
generador de color
Procesador de audio
procesador de audio
El segundo 6809E era responsable del sonido del equipo. La comunicacin se realizaba
a travs de un registro donde el procesador principal escriba y ste lea tras responder
a la interrupcin que le haca llegar el principal (ver el registro 13D en la figura).
Podemos ver tambin que este procesador tena un oscilador separado a 3,58MHz y
contaba slo con una memoria RAM de 1koct y una memoria ROM de 32koct. Las
lneas de este subsistema siguen hasta la circuitera de msica FM.
43
Circuito de sonido
44
1987 Tecmos
45
46
He aqu un extracto del cdigo fuente del multiemulador MAME20, que codifica el
circuito mostrado:
unsigned char decodebyte( unsigned char opcode, unsigned
address )
{
/*
> CPU_D7 = (EPROM_D7 & ~ADDRESS_1) | (~EPROM_D7 & ADDRESS_1) >
> CPU_D6 = EPROM_D6
> CPU_D5 = (EPROM_D5 & ADDRESS_1) | (~EPROM_D5 & ~ADDRESS_1) >
> CPU_D4 = EPROM_D4
> CPU_D3 = (EPROM_D3 & ~ADDRESS_3) | (~EPROM_D3 & ADDRESS_3) >
> CPU_D2 = EPROM_D2
> CPU_D1 = (EPROM_D1 & ADDRESS_3) | (~EPROM_D1 & ~ADDRESS_3) >
> CPU_D0 = EPROM_D0 */
unsigned char xormask;
short
xormask = 0;
if (address & 0x02) xormask |= 0x80;
else xormask |= 0x20;
if (address & 0x08) xormask |= 0x08;
else xormask |= 0x02;
return opcode ^ xormask;
}
20 El proyecto MAME es un intento de emular con un nico programa todas las mquinas
diseadas. El autor colabor con informacin tcnica sobre Combat School y Gryzor. Videre
www.mame.net
47
En los aos 90 la piratera comenz a dejar de ser rentable y fue decayendo como poco
despus caera toda la industria del videojuego de saln. El uso de circuitos grficos
ms complicados, que ya no podan realizarse con lgica discreta, el tamao creciente
de las memorias ROM que dificultaba su compra a pequea escala y la prdida de
mercado en pro de las consolas domsticas fue haciendo desaparecer la industria pirata
que goz a mediados de los aos 80 de su cenit.
48
2 Parte
Tras haber descrito la construccin de los sistemas de mquinas recreativas en la
primera parte; en esta segunda vamos a explicar cmo se realiza la emulacin de estos
equipos, teniendo en mente la plataforma PC como emuladora.
Modelo de un emulador
Vamos a presentar en esta seccin modelos UML que describen el funcionamiento de
un emulador, estos diagramas ilustran con sencillez el funcionamiento de los
programas desarrollados.
Diagrama principal
Las dos funciones bsicas que ejecuta un emulador consisten en la preparacin del
entorno y en la ejecucin en un bucle continuo- de la emulacin.
49
El arranque
Las operaciones de arranque preparan el programa para ejecutar la emulacin y
configuran algunos aspectos de la misma
procedimientos de arranque
21
50
Bucle de la emulacin
Tras el arranque del sistema, el programa entra en bucle sin fin como sigue:
51
Como vemos las acciones son esencialmente las mismas: lectura de las entradas,
ejecucin de unas instrucciones (en este caso para mover al jugador, a los enemigos, el
fondo, etc.), esperar la interrupcin que dar va libre a la pantalla sin que el usuario
note que se est modificando la imagen y el pintado en s.
El contenido de la casilla Desarrollo de la accin es lo que realmente cambia de una fase
del juego a otra o del estado de atraccin de jugadores (el famoso introduzca una
moneda) al estado de juego; las otras acciones son las mismas siempre.
52
Investigacin de Gryzor
Nada ms recibir el volcado de la ROM procedente de Lewin Edwards (Australia) lo
nico que se poda ver era:
Directorio de C:\pfc\gryzor\Rom
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
20/09/1997
18:33
32.768 G-1.ROM
18:48
65.536 G-10.ROM
18:49
65.536 G-11.ROM
18:50
65.536 G-12.ROM
18:51
65.536 G-13.ROM
18:51
65.536 G-14.ROM
18:52
65.536 G-15.ROM
18:53
65.536 G-16.ROM
18:54
65.536 G-17.ROM
18:55
65.536 G-18.ROM
18:35
65.536 G-2.ROM
18:37
65.536 G-3.ROM
18:39
65.536 G-4.ROM
18:43
65.536 G-5.ROM
18:44
65.536 G-6.ROM
18:46
65.536 G-7.ROM
18:47
65.536 G-8.ROM
18:47
65.536 G-9.ROM
18 archivos
1.146.880 bytes
0 dirs
1.827.024.896 bytes libres
Un total de 18 archivos y algo ms de 1Moct, comparado con los escasos 300 koct de
G&G el juego prometa! Afortunadamente algo se saba de la placa: llevaba dos
53
Fichero g-1.rom
Al ejecutar d6809 g-1.rom > g-1.s y leer la salida vemos:
ORG $0000
0000: F7 60
0003: F6 20
0006: C4 80
0008: 26 F9
000A: B7 20
000D: F6 20
22
01
STB
$6022
LDB
$2001
ANDB #$80
BNE
$0003
00
STA
$2000
01
LDB
$2001
0010: C4 80
0012: 26 F9
0014: F6 60 22
0017: F7 20 01
001A: 39
001B:
001E:
0020:
0023:
0025:
0028:
CC
8D
CC
8D
CC
20
14 39
E0
12 F9
DB
14 3B
D6
ANDB
BNE
LDB
STB
RTS
#$80
$000D
$6022
$2001
LDD
BSR
LDD
BSR
LDD
BRA
#$1439
$0000
#$12F9
$0000
#$143B
$0000
etc.
10
4F
A7
10
26
10
86
1F
1C
BD
86
8E 60 00 LDY
CLRA
A0
STA
8C 67 FF CMPY
F8
BNE
CE 68 00 LDS
60
LDA
8B
TFR
EF
ANDCC
82 B5
JSR
07
LDA
#$6000
,Y+
#$67FF
$002F
#$6800
#$60
A,DP
#$EF
$82B5
#$07
Es importante tomar nota de posiciones explcitas de memoria pues indican puertos de E/S
(dispositivos mapeados en memoria)
22
54
B7
86
B7
8D
CC
8D
F6
5C
C1
60
08
60
CB
08
AB
60
31
34
00
22
08
STA
LDA
STA
BSR
LDD
BSR
LDB
INCB
CMPB
$6031
#$08
$6034
$001B
#$0800
$0000
$6022
#$08
Para que este cdigo sea coherente ha de cumplir que no presuponga nada, puesto que
suponemos que es el de arranque del procesador. Si seguimos las instrucciones vemos
que efectivamente el cdigo comienza a construir el proceso sin suponer ningn valor
conocido en registros ni en memoria. As que aceptamos la hiptesis: este fichero
corresponde a un 6809 y ocupa los 32koct superiores de la memoria.
Siguiendo con el desensamblado llegamos a puntos tales como:
0698:
069B:
069D:
069F:
06A1:
06A3:
06A5:
06A7:
06A8:
06AA:
06AB:
06AD:
06AE:
06B0:
06B1:
06B3:
06B6:
06B9:
etc.
FE
0F
1F
00
00
1F
00
01
90
12
00
01
90
12
00
CE
BD
CC
00 00
0A
00
F8
8C
16
F8
1F
F8
1F
F8
86 98
83 FC
07 50
LDU
$0000
CLR
$0A
TFR
D,D
NEG
$F8
NEG
$8C
TFR
X,inv
NEG
$F8
Illegal Opcode
SUBA $1F
NOP
NEG
$F8
Illegal Opcode
SUBA $1F
NOP
NEG
$F8
LDU
#$8698
JSR
$83FC
LDD
#$0750
55
Fichero G-2.rom
Al comenzar a desensamblar este fichero lo primero que encontramos es desolador:
0000:
0002:
0004:
0006:
0008:
000A:
000C:
000E:
etc.
00
00
00
00
10
10
10
10
00
00
00
00
00
00
00
00
NEG
$00
NEG
$00
NEG
$00
NEG
$00
Illegal Opcode
Illegal Opcode
Illegal Opcode
Illegal Opcode
A6
84
E6
EA
C4
26
8A
A7
39
10
BF
13
03
01
02
40
10
LDA
ANDA
LDB
ORB
ANDB
BNE
ORA
STA
RTS
$FFF0,X
#$BF
$FFF3,X
$0003,X
#$01
$EF64
#$40
$FFF0,X
4F
B7
97
B7
7E
00 07
F0
70 00
61 11
CLRA
STA
STA
STA
JMP
$0007
$F0
$7000
$6111
56
70
06
06
00
61
1C
70
06
06 80
70
60
01
06
06 80
90
NEG
$0680
ROR
$70
ROR
$60
NEG
$01
Illegal Opcode
ANDCC #$06
NEG
$0680
ROR
$90
cdigo absurdo y con instrucciones ilegales. Hemos obtenido adems otra informacin
adicional: el segmento 6000h-7FFFh de G-2.rom no corresponde a la pgina nmero
cero, sea cual sea el registro de paginacin. Cmo sabemos que no es la pgina cero?
Porque el proceso seleccion la pgina cero antes de saltar a 6111h, si este segmento no
contiene nada vlido en esa posicin es porque no es la respuesta.
Dnde esta el cdigo correspondiente a 6111h? Antes de responder esta pregunta,
echemos un vistazo al siguiente archivo.
57
Fichero G-3.rom
El comienzo del desensamblado de este fichero no podra ser ms halageo:
0000:
0002:
0005:
0007:
0009:
000B:
000E:
0011:
0014:
0016:
0018:
001B:
001D:
001F:
0021:
0023:
0025:
etc.
8D
CE
96
84
26
CE
BD
BD
86
97
CC
A7
E7
33
0A
26
39
24
30
F1
08
03
38
60
60
11
54
F0
42
44
45
54
F6
00
00
B5
AE
08
BSR
LDU
LDA
ANDA
BNE
LDU
JSR
JSR
LDA
STA
LDD
STA
STB
LEAU
DEC
BNE
RTS
$0026
#$3000
$F1
#$08
$000E
#$3800
$60B5
$60AE
#$11
$54
#$F008
$0002,U
$0004,U
$0005,U
$54
$001B
Una rutina completa y con sentido. Las sorpresas no acaban aqu, si cargamos el
fichero con un editor hexadecimal encontramos resultados como el mostrado en la
imagen inferior:
Como vemos aparecen multitud de palabras legibles en ASCII, tales como: COIN1,
COIN2,DEMO SOUND, DIFFICULTY, FIRST AT, EASY,TEST, DIP, SERVICE, etc.
Sin lugar a dudas nos encontramos ante un nuevo fichero de cdigo de 6809, otros
64koct ms de programa. Antes de seguir investigando el funcionamiento del juego
veamos qu hay en los otros archivos.
58
STA
RTS
$602C
Almacena A, cuyo valor era cero, y vuelve... realmente no tiene sentido puesto que la
llamada a 6111h era en realidad un salto y no una invocacin a subrutina. Descartamos,
por tanto, el bloque 0000-1FFFh de G-2. rom como pgina cero. Veamos el siguiente:
2000h-3FFFh:
2111:
2113:
2115:
2117:
23
23
23
23
2A
2D
05
04
BLS
BLS
BLS
BLS
$213D
$2142
$211C
$211D
59
LEAU
$FFF3,Y
No cabe discusin alguna sobre sta: utiliza el registro Y pero ste no haba sido
iniciado antes, no puede ser, por tanto, la que buscamos. Aun queda el bloque 6000h7FFFh:
6111:
6114:
6116:
6118:
611A:
70
06
06
00
61
06 80
70
60
01
NEG
$0680
ROR
$70
ROR
$60
NEG
$01
Illegal Opcode
Una vez ms hemos fracasado en la bsqueda. Vayamos ahora al siguiente fichero: g3.rom, comenzando desde el principio:
0111:
0113:
0115:
0118:
011B:
011D:
011F:
0120:
etc.
86
C6
8E
B7
30
26
5A
26
01
05
80 00
00 1E
1F
F9
F3
LDA
LDB
LDX
STA
LEAX
BNE
DECB
BNE
#$01
#$05
#$8000
$1E
$FFFF,X
$0118
$0115
El fragmento mostrado tiene doble lgica: no presupone valores en los registros como
corresponde al arranque- y es un bucle de espera. Qu mejor hacer al arrancar el
equipo que esperar a que el monitor se encienda completamente? En el interior del
doble bucle (resaltado en verde) vemos insistentes escrituras del valor 1 en la posicin
001E, lo que indica con pocas dudas- que esa es la posicin del registro de
autoarranque23.
Ya estamos tras la pista correcta, ahora queda seguir leyendo el cdigo fuente con ojos
crticos para ir averiguando ms y ms. Tras la espera, el programa sigue su labor
iniciando diversas posiciones de memoria con valores conocidos hasta que llega a24:
6182:
6183:
6186:
6189:
618C:
618E:
6190:
6192:
6195:
4F
CE
8E
B7
A7
30
26
CE
8E
10
10
00
C0
1F
F7
10
10
00
00
1E
00
00
CLRA
LDU
LDX
STA
STA
LEAX
BNE
LDU
LDX
#$1000
#$1000
AUTOARRANQUE
,U+
$FFFF,X
$6189
#$1000
#$1000
60
CMPA
,U+
LEAX
BNE
ADDA
CMPA
BNE
$FFFF,X
$6198
#$55
#$54
$6183
Binario
00000000
01010101
10101010
11111111
La secuencia de valores cumple la condicin de haber hecho pasar a todos los dgitos
por 1 y por 0. Estamos, por tanto, ante un fragmento de cdigo que verifica el
funcionamiento correcto en cuanto a lectura y escritura de todos los dgitos desde
1000h hasta 1FFFh. Lo que se deduce de esto es que la regin 1000h-1FFFh es una
memoria RAM de 4koct. Esta informacin es fundamental a la hora de ir elaborando el
mapa de memoria de la mquina.
Si lo anterior era una verificacin de la RAM, qu ocurra si sta fallaba? Siguiendo la
rutina vemos que en caso de error se salta a 62ED, busquemos ese procedimiento:
62ED:
62F0:
62F3:
62F4:
62F6:
62FA:
62FE:
6300:
6303:
8E
CE
5F
A6
10
E7
A7
30
20
26 49
63 05
LDX
LDU
CLRB
C0
LDA
27 1D 06 LBEQ
89 FC 00 STB
84
STA
88 E0
LEAX
EF
BRA
#$2649
#$6305
,U+
$8000
$FC00,X
,X
-$20,X
$62F4
61
Caracteres de Gryzor
Cada fila tiene 16 bloques, interpretando la secuencia anterior podemos leer: 13D BAD.
Es bien sabido que en las placas electrnicas se nombran los componentes siguiendo
una matriz de nmeros y letras para filas y columnas. Este escueto mensaje nos indica
que el integrado en la posicin 13D no funciona.
Aun hay ms informacin de valor en ese fragmento de cdigo. Para escribir el
mensaje en pantalla se han realizado escrituras en 2649 y 2249, adems las hechas en
2249 han sido siempre ceros. De aqu se colige la siguiente hiptesis: hay un circuito
grfico mapeado desde las posiciones 2000 hasta 27FF que se descompone en dos, uno
ocupa 2000-23FF y contiene los atributos de los bloques y otro ocupa 2400-27FF y
contiene el nmero de bloque. Un tamao de 400h octetos equivale a 322, es decir 32
filas por 32 columnas, rellenos con bloques de 8x8 puntos equivale a 256x256 puntos.
Hemos deducido la resolucin de la pantalla!
Aun no acaba aqu, esas nueve lneas de cdigo nos van a decir algo ms: el monitor
est girado. Ya sabamos que los grficos estaban girados 90 (vide codificacin grfica
de Gryzor) pero ahora vemos adems que el programa ha escrito el mensaje de abajo a
arriba: cada carcter est 20h bloques antes que el anterior, es decir 32 bloques, que
segn nuestra hiptesis equivale a una fila. La mquina esta imprimiendo cada
mensaje encima del siguiente, sin embargo han de verse en posicin horizontal en el
monitor: conclusin, el monitor est volcado 90. Esto es de capital importancia a la
hora de realizar las rutinas grficas.
Cabe preguntarse, por qu usar el monitor tumbado? Bien, Gryzor tena una pantalla
algo ms larga que ancha, pese a que de momento trabajamos con la hiptesis de
256x256 puntos eso slo atae a este circuito grfico; la resolucin total aun est por
hallar. Otra pregunta vlida sera Por qu suponemos que esta todo girado en la
placa: los grficos, la pantalla... no podra ser ese su funcionamiento normal? La
realidad es que la circuitera grfica de un videojuego sola utilizarse en otros, lo ms
sensato es pensar que estos circuitos se disearon para monitores horizontales y aqu
se usan con uno en vertical, a costa de complicar la programacin y de girar los
grficos.
Tras ese cdigo verificador se suceden ms secuencias del mismo estilo, comprobando
cada vez distintas reas; como la [C00,D00[ (correspondiente a la paleta grfica); la
[2000,4000[ (los circuitos grficos) y la [4000,6000[. Acto seguido el programa vuelve a
la posicin 800C, justo despus de la llamada a 6111 ya comentada.
62
CE
CC
DD
CC
DD
BD
0C
0A
26
10
27
96
8A
97
8E
10
BD
DD
CC
DD
BD
0C
0A
26
10
27
96
8A
97
4F
80
00
5C
00
5E
80
5E
5F
F7
A3
06
58
80
58
80
8E
80
5C
08
5E
80
5E
5F
F7
A3
06
59
80
59
E6
00
LDU
LDD
STD
08
LDD
STD
D3
JSR
INC
DEC
BNE
C1
CMPD
BEQ
LDA
ORA
STA
00
LDX
00 00 LDY
C5
JSR
STD
04
LDD
STD
D3
JSR
INC
DEC
BNE
C1
CMPD
BEQ
LDA
ORA
STA
CLRA
#$80E6
#$0000
$5C
#$0008
$5E
$80D3
$5E
$5F
$8019
,U++
$802D
$58
#$80
$58
#8000
#$0000
$80C5
$5C
#$0804
$5E
$80D3
$5E
$5F
$803E
,U++
$8052
$59
#$80
$59
63
Microsoft Foundation Classes (Clases Bsicas de Microsoft). Las MFC son un conjunto de clases
de C++ que ofrecen una base para desarrollar aplicaciones ms rpidamente que con C puro.
26 Sistemas Electrnicos Digitales, antigua asignatura del tercer ao de Ingeniera de
Telecomunicaciones en la UPV
25
64
Uso
Cuando se ejecuta el Analizador, tras una pantalla de presentacin, se nos ofrece una
ventana tpica de una aplicacin MDI27. Los elementos se describen a continuacin:
65
66
Borrar el comentario: basta pulsar suprimir para eliminar el comentario, del tipo
que fuere, del desensamblado
El men Memoria
67
cuadro de registros
Cuando la ventana activa es una vista grfica, el men ver se ampla a las siguientes
opciones:
28
68
La idea del cdigo anterior es simular los registros con una estructura, la memoria con
un vector y el conjunto de operaciones por una funcin (ejecuta_op). Se ha representado
tambin el uso del registro de puntero de instruccin (IP), como se sabe este registro
apunta a la siguiente instruccin a ejecutar; despus de procesarla, el contenido del
registro ha de incrementarse para pasar a la siguiente29.
Cmo podemos realizar la funcin ejecuta_op? Lo ms obvio es utilizar la
construccin case:
#define SUMAR 0x12 /*Cdigo mquina de la suma */
#define RESTAR 0x13 /* dem de la resta */
switch( op )
{
case SUMAR: haz_suma(); break;
case RESTAR:haz_resta(); break;
}
Este enfoque con un compilador adecuado puede producir cdigo muy rpido. Para
ello es necesario que la direccin de memoria donde salta el cdigo est relacionada
con el nmero de la operacin. Es decir, queremos que la direccin donde salta el
programa a partir de la instruccin switch se componga de:
29
69
En el caso de que el compilador no sea capaz de generar esta tabla de forma automtica se
puede realizar utilizando un vector de punteros a funcin de la siguiente forma:
void haz_suma();
void haz_resta();
...
void (*funciones())[256];
funciones[0] = haz_suma;
funciones[1] = haz_resta;
(funciones[op])(); /* Llama a la funcin en la posicin op*/
70
Debido a que el coste de ejecucin de una operacin es elevado en cuanto a coste fijo:
entrar en la funcin que evala cul se ejecuta y salir de ella; trataremos de reducir ese
coste ejecutando lotes de operaciones en un bucle, se ahorran as apilaciones y
desempilaciones de datos. El inconveniente es que las interrupciones no son emuladas
de forma muy realista, ya que en lugar de parar la ejecucin del programa en cualquier
instante lo harn slo en medio de uno de estos paquetes. En la prctica no se aprecia
la diferencia, en especial porque la nica interrupcin que ocurre habitualmente en una
mquina de vdeo proviene del sistema de vdeo y dada la estructura del juego, el
cdigo debe estar en un bucle de espera de la interrupcin cuando sta llega; no
importa, por tanto, realmente que se interrumpa el hilo de ejecucin en un punto u otro.
71
El Motorola 6809
El procesador M6809 es una UCP de 8 dgitos, CISC, con un juego de registros
reducido:
Nombre
A
B
X
Y
U
S
CC
DP
PC
Tamao (octetos)
1
1
2
2
2
2
1
1
2
Descripcin
acumulador
acumulador
ndice
ndice
ndice
ndice para la pila
banderas
ndice directo
puntero de operacin
72
73
Juego de instrucciones
Banderas
(CC)
Modo de direccionamiento
Immediat
Directo
o
Instrucci Nemnic
Op ~
n
o
# Op
Indexado
Extendid
Inherente
o
~ # Op ~ # Op ~ #
ABX
A = A+M+C
+
+
+ ++ +
+ ++ +
ADCB
C9 2
2 D9
4 2 E9
4
2+ F9 5 3
+
B = B+M+C
+ ++ +
ADDA
8B 2
2 9B
4 2 AB
4
2+ BB 5 3
+
A = A+M
+ ++ +
ADDB
CB 2
2 DB
4 2 EB
4
2+ FB 5 3
+
B = B+M
+ ++ +
ADDD
C3 4
3 D3
6 2 E3
6
2+ F3 7 3
+
D = D+M:M+1
+ ++ +
84 2
2 94
4 2 A4 4 2+ B4 5 3
+
A = A && M
+ +0
C4 2
2 D4
4 2 E4 4 2+ F4 5 3
+
B = B && M
+ +0
1C 3
C = CC &&
?
INM
? ? ? ?
ANDB
ASLB
08
6 2 68
48 2
58 2
6
2+ 78 7 3
+
ASRA
47 2
ASRB
57 2
ASR
07
6 2 67
6
2+ 77 7 3
+
8
desplazamient
o aritmtico a 8
la izquierda
8
8
desplazamient
o aritmtico a 8
la derecha
8
+ ++ +
+ ++ +
+ ++ +
+ +
+ +
+ +
BITA
85 2
2 95
4 2 A5
4
2+ B5 5 3
+
probar dgito
en A (M&&A)
+ +0
BITB
C5 2
2 D5
4 2 E5
4
2+ F5 5 3
+
probar dgito
en B (M&&B)
+ +0
BIT
CLRA
4F 2
A=0
0 1 0 0
CLRB
5F 2
B=0
0 1 0 0
M=0
0 1 0 0
0F
CLR
CMP
X = B+X (sin
signo)
4
2+ B9 5 3
+
ASL
CLR
NZV C
4 2 A9
ASLA
ASR
3
3
A
2 99
ANDCC
ASL
Descripcin
89 2
ANDA
AND
3 2 1 0
ADCA
ADC
ADD
O
~
p
6 2 6F
6 2+ 7F 7 3
+
CMPA
81 2
2 91
4 2 A1 4 2+ B1 5 3
+
compara M con 8
A
+ ++ +
CMPB
C1 2
2 D1
4 2 E1 4 2+ F1 5 3
+
compara M con 8
B
+ ++ +
CMPD
10 5
83
4 10
93
7 3 10 7 3+ 10 8 4
A3 +
B3
compara
M:M+1 con D
+ ++ +
CMPS
11 5
8C
4 11
9C
7 3 11 7 3+ 11 8 4
AC +
BC
compara
M:M+1 con S
+ ++ +
CMPU
11 5
83
4 11
93
7 3 11 7 3+ 11 8 4
A3 +
B3
compara
M:M+1 con U
+ ++ +
74
COM
CMPX
8C
3 9C
6 2 AC 6 2+ BC 7 3
+
compara
M:M+1 con X
+ ++ +
CMPY
10 5
8C
4 10
9C
7 3 10 7 3+ 10 8 4
AC +
BC
compara
M:M+1 con Y
+ ++ +
COMA
43 2
A
=
complemento(
A)
+ +0 1
COMB
53 2
B
=
complemento(
B)
+ +0 1
M
=
complemento(
M)
+ +0 1
COM
CWAI
03
3C
6 2 63
6
2+ 73 7 3
+
CC = CC ^
INM;
espera hasta la 7
prxima
interrupcin
=>
2
20
19 2
ajuste decimal
A
+ +0 +
DECA
4
2
A
A=A 1
+ ++
DECB
5
2
A
B=B 1
+ ++
DAA
DEC
DEC
0A
6 2 6A
6
2+ 7A 7 3
+
M=M 1
+ ++
EORA
88 2
2 98
4 2 A8
4
2+ B8 5 3
+
A = A XOR M
+ +0
EORB
C8 2
2 D8
4 2 E8
4
2+ F8 5 3
+
B = M XOR B
+ +0
R1,R2
1E 8
EOR
EXG
Intercambia
R1,R2
INCA
INC
INCB
4C 2
A=A+1
+ ++
5C 2
B=B+1
+ ++
M=M+1
+ ++
0C
6
6 2 6C
2+ 7C 7 3
+
JMP
0E
3 2 6E
3
2+ 7E 4 3
+
pc = EA
JSR
9D
7 2 AD
7
2+ BD 8 3
+
salto
subrutina
INC
LD
LDA
86 2
2 96
4 2 A6 4+ 2 B6 5
+
LDB
C6 2
2 D6
4 2 E6 4+ 2 F6 5
+
LDD
CC
3 DC
5 2 EC 5+ 2 FC 6
+
LDS
10 4
CE
4 10
DE
6 3 10 6+ 3 10 7
EE
+ FE
LDU
CE
3 DE
5 2 EE 5+ 2 FE 6
+
LDX
8E
3 9E
5 2 AE 5+ 2 BE 6
+
LDY
10 4
8E
4 10
9E
6 3 10 6+ 3 10 7
AE
+ BE
A=M
B=M
a
++0
++0
D = M:M+1
++0
S = M:M+1
++0
U = M:M+1
++0
X = M:M+1
++0
Y = M:M+1
++0
75
LEA
LSL
LEAS
32 4+ 2
+
S = EA
LEAU
33 4+ 2
+
U = EA
LEAX
30 4+ 2
+
X = EA
LEAY
31 4+ 2
+
Y = EA
LSLA
48 2
LSLB
58 2
LSL
LSR
08
6 2 68 6+
2
78 7
+
LSRA
44 2
LSRB
54 2
LSR
04
6 2 64 6+
2
74 7
+
3
3
11
D
MUL
NEG
D = A*B (sin
signo)
+++ +
0 +
0 +
0 +
A = !A + 1
8+++ +
B = !B + 1
8+++ +
M = !M + 1
8+++ +
00
6 2 60 6+
2
70 7
+
3
12 2
ORB
No hace nada
8A 2
2 9A
4 2 A 4+ 2 BA 5
A
+
A = A || M
++0
CA 2
2 DA
4 2 EA 4+ 2 FA 5
+
B = B || M
++0
1A 3
C =
IMM
CC
PSHS
34 5+ 2
Meter en S
PSHU
36 5+ 2
Meter en U
PULS
35 5+ 2
Sacar de S
PULU
37 5+ 2
Sacar de U
ROLA
49 2
ROLB
59 2
ROL
09
6 2 69 6+
2
79 7
+
RORA
ROR
Desplazamient
o a la derecha
+++ +
50 2
ORCC
ROL
Desplazamient
o a la izquierda
40 2
ORA
PUL
+++ +
NEGB
NOP
PSH
NEGA
NEG
OR
RORB
ROR
06
2
6 2 66 6+
76 7
+
46 2
56 2
||
Rotar
a
la
izquierda con
acarreo
Rotar
a
la
derecha
con
acarreo
?? ? ? ?
+++ +
+++ +
+++ +
0 +
0 +
0 +
RTI
3B 6/15 1
Retorno
de
?? ? ? ?
interrupcin
RTS
39 5
Retorno
subrutina
SBCA
SBC
SBCB
2 92
4 2 A2 4+ 2 B2 5
+
A=A-M-C
8+++ +
C2 2
2 D2
4 2 E2 4+ 2 F2 5
+
B=B-M-C
8+++ +
1
2
D
STA
de
82 2
SEX
ST
97
4 2 A7 4+ 2 B7 5
+
Extender
el
signo de A en B
M=A
++0
++0
76
D7
4 2 E7 4+ 2 F7 5
+
DD
5 2 ED 5+ 2 FD 6
+
10
DF
6 3 10 6+ 3 10 7
EF
+ FF
DF
5 2 EF 5+ 2 FF 6
+
9F
5 2 AF 5+ 2 BF 6
+
10
9F
6 3 10 6+ 3 10 7
AF
+ BF
80 2
2 90
4 2 A0 4+ 2 B0 5
+
C0 2
2 D0
4 2 E0 4+ 2 F0 5
+
83 4
3 93
6 2 A3 6+ 2 B3 7
+
STD
STS
STU
STX
STY
SUBA
SUB
SUBB
SUBD
SWI
TST
++0
M:M+1 = S
++0
M:M+1 = U
++0
M:M+1 = X
++0
M:M+1 = Y
++0
A=A-M
8+++ +
B=B-M
8+++ +
D = D - M:M+1
1
interrupcin
por programa 1
SWI2
10 20
3F
interrupcin
por programa 2
SWI3
11 20
3F
interrupcin
por programa 3
SYNC
TFR
M:M+1 = D
3F 19
SWI
13
R1,R2
1F 6
++0
M=B
>=
4
+++ +
sincronizarse
con
la
interrupcin
R2 = R1
TSTA
4
2
D
prueba A
++0
TSTB
5
2
D
prueba B
++0
prueba M
++0
TST
0D
6 2 6D 6+
2
7D 7
+
Leyenda
! Complemento de M
+ afectado
OP cdigo de la operacin
(hexadecimal)
= asignacin
- no se afecta
# nmero de octetos
N bandera de signo
: Concatenation
+ suma aritmtica
Z cero
|| o lgica
- resta aritmtica
V desbordamiento,
complemento a 2
&& y lgica
* multiplicacin
C acarreo de la UAL
EOR o xclusiva
EA direccin efectiva: w
77
El compilador de un emulador
El emulador del procesador es una pieza clave en la velocidad del conjunto del
programa y su fiabilidad imprescindible ya que quando caput dolet caetera membra
dolent30, es decir, si el director de la orquesta presenta fallos la emulacin no funcionar.
Durante el desarrollo del emulador de Ghosts & Goblins descubrimos accidentalmente
una situacin curiosa relacionada con la importancia de un procesador bien emulado.
Cuando haca las primeras pruebas del juego funcionando con la UCP emulada todo
pareca ir bien hasta que programamos las rutinas de entrada de monedas y pudimos
comenzar la partida. En la escena de introduccin aparece un vampiro enorme que
secuestra a la doncella y da comienzo a la accin, en su ataque, el vampiro recorre una
lnea recta oblicua desde el cielo hasta el suelo, donde yace la dama. Curiosamente si la
operacin de rotacin con acarreo de los dgitos est implementada como
desplazamiento a secas31 el vampiro no es capaz de atrapar a la doncella y queda
eternamente dando vueltas alrededor de la pantalla quedndose colgado el juego.
Como vemos una instruccin mal emulada puede detener completamente el proceso,
la relacin entre el error visual (el vampiro dando vueltas) y el error real (desplazar por
rotar) no es obvia y su depuracin puede llevar varias horas o no encontrarse nunca.
Teniendo en cuenta el nmero de instrucciones a codificar la probabilidad de cometer
errores es enorme, mxime si se pretende escribir el emulador en ensamblador para
maximizar su velocidad.
Tras un par de tentativas fracasadas ante erratas imposibles de encontrar se lleg a la
conclusin de que la mejor forma de escribir un emulador era no escribindolo,
compilndolo.
Todas las rdenes del procesador tienen una gran simetra entre s: todas cargan datos
de memoria, todas operan sobre ellos y todas alteran las banderas. La forma de cargar
los datos y de afectar las banderas es tambin comn: todas las rdenes que cargan de
modo indexado lo hacen igual, todas las que modifican la bandera de cero lo hacen por
Cuando duele la cabeza, duelen el resto de los miembros
Rotacin implica que no se pierde informacin, que el dgito que sale por un extremo entra
por el otro; en el desplazamiento se pierden dgitos que se sustituyen por cero
30
31
78
A continuacin se detalla el fichero crea.gen32 que contiene todas las instrucciones, tras
l se analizarn algunas instrucciones de cada tipo y la codificacin que genera el
compilador por nosotros programado- de ellas.
Se decidi nominar la extensin como gen en alusin a que este fichero era la gnesis del
emulador
32
79
89,
c9,
8B,
CB,
c3,
HNZVC,
HNZVC,
HNZVC-,
HNZVC-,
hnzvc-,
"adcb @,%bh"
"adcb @,%bl"
"addb @,%bh"
"addb @,%bl"
"add %ax,%bx"
Aade
Aade
Aade
Aade
Aade
el
el
el
el
el
valor
valor
valor
valor
valor
a
a
a
a
a
A con acarreo
b con acarreo
A
B
D
clra,
, 4F, N0 Z1 V0 C0 -, "xor
clrb,
, 5F, N0 Z1 V0 C0 -, "xor
clr, dxe+,
f, n0 z1 v0 c0 -, "movb
%bh,%bh" Borra A
%bl,%bl" Borra B
$0,(%ebp,%eax)" Borra el octeto
inca,,4c,nzv-,"inc
%bh"
incb,,5c,nzv-,"inc
%bl"
inc,dxe+,c,nzv-,"incb
(%ebp,%eax)"
jmp, dxe+, 0E,-,"movw
%ax,%si" Salto incondicional
jsr,
dxe+,
9d,-,"mov
%si,%dx
\nxchg
%dh,%dl
\
subw
\nxor %ecx,%ecx\nmovw _s,%ecx \nmovw %dx,(%ebp,%ecx) \nmov %ax,%si"
lda, idxe, 86,
ldb, idxe, c6,
ldd,0idxe, cc,
lds,0idxe,10CE,
ldu,0idxe, ce,
nzv-,
nzv-,
nzv-,
nzv-,
nzv-,
"movb
"movb
"movw
"movw
"movw
$2,_s
@,%bh\naddb
$0,%bh" Carga el valor en A
@,%bl\naddb
$0,%bl" Carga el valor en B
%ax,%bx\naddw
$0,%bx" Carga el valor en D
%ax,_s \naddw
$0,%ax" Carga el valor en S
%ax,_u \naddw
$0,%ax" Carga el valor en U
80
%ax,_x \naddw
%ax,_y \naddw
$0,%ax\nje
leax_z\nandl
$0,%ax\nje
leay_z\nandl
_s,%ax
\nmovw
(%ebp,%eax),%ax\nxchg
%ah,%al
sbca,idxe,82,hnzvc,"sbbb @,%bh"
sbcb,idxe,c2,hnzvc,"sbbb @,%bl"
sex,,1d,nz-,"mov
$0,%bh" V = 0 siempre
$0,%bl" V = 0 siempre
$0,(%ebp,%eax)" V = 0 siempre
81
82
"adcb
La instruccin adca est codificada como adcb @,%bh en cdigo Intel, representando
que se aadir al registro A (emulado con el registro bh del 8086) el valor del operando
representado por @, ste se obtendr segn el modo de direccionamiento: inmediato,
directo, indexado o extendido. Adems las banderas de cuarteto, de signo, de cero, de
desbordamiento y de acarreo resultarn afectadas. Para optimizar la velocidad, cada
modo de direccionamiento se codifica con una funcin distinta; el cdigo que genera el
compilador es:
.align 4
_adcaI:
#adca Inmediato
pushl
CCF
popfl
inc %si
#cdigo singular
adcb -1(%ebp,%esi),%bh
#final
pushfl
popl
CCF
ret
adca, inmediato
.align 4
_adcaX:
#adca Indexado
xor %eax,%eax
movb (%ebp,%esi),%al
lea _index,%ecx
incw %si
call (%ecx,%eax,4)
pushl
CCF
popfl
#cdigo singular
adcb (%ebp,%eax),%bh
#final
pushfl
popl
CCF
ret
adca, indexado
.align 4
_adcaD:
#adca Directo
xor %eax,%eax
#carga en EAX el octeto de desplazamiento
movb (%ebp,%esi),%al
inc
%si #ajusta el PC
movb
_dp,%ah # Pone en AH DP
pushl
CCF
popfl
#cdigo singular
adcb (%ebp,%eax),%bh
#final
pushfl
popl
CCF
ret
adca, directo
.align 4
_adcaE:
#adca Extendido
xor %eax,%eax
movw (%ebp,%esi),%ax
addw
$2,%si #ajusta el PC
xchgb %ah,%al #direccin en EAX
pushl
CCF
popfl
#cdigo singular
adcb (%ebp,%eax),%bh
#final
pushfl
popl
CCF
ret
adca, extendido
83
Descripcin
Es el compilador del fichero gnesis descrito
anteriormente
Genera el cdigo de la operacin de intercambio
EXG
dem con la instruccin de transferencia, TFR
Genera el cdigo del direccionamiento indexado
dem de la instruccin de apilar con el registro S o
con el U
dem de la instruccin de desempilar con el
registro S o con el U
Ficheros resultantes
6809.s
ops.s
rellena.s
Exg.s, exg.re
Tfr.s, tfr.re
Index.s, index.re
Pshs.s, pshs.re
pshu.s, pshu.re
Puls.s, puls.re
Pulu.s, pulu.re
84
donde el nombre se compone del prefijo _exg seguido del cdigo del operando en
hexadecimal.
Cuando el procesador encuentra una operacin EXG salta en primer lugar al siguiente
cdigo en ensamblador (extrado de 6809.s):
85
Desde aqu se realiza un nuevo salto en base al operando que se utiliza como ndice de
la tabla de punteros _exgTabla. Ntese que no se realiza una llamada a subrutina sino
un salto incondicional jmp, de esta forma la orden de retorno sita al final de cada rutina
_exgXX volver no a esta rutina si no a la que llam a sta. El resultado: el procesador
evita la ejecucin de una instruccin ret adicional y un posible borrado de cach. Esta
idea y otras similares se han usado hasta el agotamiento en todo el emulador.
Los restantes programas: TFR, y los cuatro relacionados con la pila PSHU/S, PULU/S;
generan ficheros similares a ste y se basan en la misma optimizacin de cambiar
espacio en memoria por velocidad de ejecucin.
El direccionamiento indexado
Como ya se vi cuando se explicaron los modos de direccionamiento, bajo la
denominacin de direccionamiento indexado se esconden muchsimos casos distintos y
la lgica aplicable a EXG tiene validez aqu tambin: en lugar de analizar el operando
cada vez, es ms rpido tener rutinas separadas para ocasin. El fichero ensamblador
generado por este programa contiene ms de 1500 lneas de cdigo y desmenuza
absolutamente este modo de direccionamiento.
Vamos a mostrar someramente el programa en C encargado de generar ese cdigo
ensamblador. La funcin main es sencillamente un bucle que evala los 256 posibles
casos y segn cada uno invoca a una funcin encargada de escribir esa operacin
concreta.
void main()
{
/
for( con=0; con<=255; con++ ) {
modo = con; /* lo convertimos a 8-dgitos */
if ( (modo&0x80)==0 ) desp5();
else
switch( modo & 0xf ) {
case 0: post1(); break;
case 1: post2(); break;
case 2: pre1(); break;
case 3: pre2(); break;
case 4: solo_reg(); break;
case 5: accB();
break;
case 6: accA();
break;
case 8: desp8();
break;
case 9: desp16();
break;
case 11:accD();
break;
case 12:pc8();
break;
case 13:pc16();
break;
case 15:extI();
break;
}}}
86
Esta macro se utiliza en ensamblador para rellenar las tablas con las direcciones de las
funciones. Todos los generadores crean ficheros con extenin re cuyo contenido son
invocaciones a esta macro, por ejemplo la anterior funcin en C genera entradas como:
RELLENA _desp8_y_I,0xB8
87
88
La funcin Ejecuta
Esta es la funcin que une al emulador del procesador con el resto del programa. ste
dir ejecuta(10) y diez instrucciones sern simuladas. Algunos registros del 6809 se
colocan en el interior del x86 para acelerar la emulacin, a esto lo llamaremos registro
emulado internamente, estos son:
Registro 6809
A
B
PC + puntero a la RAM
Operando
Puntero a la RAM
Registro x86
Bh
Bl
ESI
AX
EBP
16(%esp),%eax
%eax,contador
_a,%bh
_b,%bl
_ram,%ebp
%esi,%esi
_pc,%si
otra_instruccion:
xor %eax,%eax
movb (%ebp,%esi),%al
lea
_ops,%ecx
inc %si
call
(%ecx,%eax,4)
decl
contador
jnz
otra_instruccion
movb
movb
movw
%bh,_a
%bl,_b
%si,_pc
popl %ebp
popl %edi
popl %esi
ret
89
Cada instruccin del 6809 afecta a todos, algunos o ninguno de estos indicadores. Por
ejemplo la instruccin daa (ajuste decimal, utilizada con nmeros codificados en BCD)
no altera ninguna de las banderas pero la instruccin asl (desplazamiento a la
izquierda) las modifica todas.
Evaluar cada condicin posible al final de cada instruccin es simultneamente un
engorro de programar, una fuente de errores y una considerable prdida de tiempo de
proceso. Si la capacidad para realizar esta comprobacin est ya imbuida en el
procesador x86 por qu no utilizarla? Nada ms ejecutar una instruccin el x86
modifica sus propias banderas en funcin del resultado as que parecera que no hay
ms que copiar su valor a la variable que simula el registro del 6809; sin embargo hay
que tomar algunas precauciones:
1. Muchas instrucciones no slo modifican las banderas sino que requieren de su
valor para operar correctamente.
2. No todas las rdenes del 6809 afectan los mismos dgitos que sus homnimas
del x86, en algunos casos no hay ninguna correspondencia. Estas excepciones
son muy peligrosas.
3. El tamao del registro del 6809 es de un octeto, el del x86 de cuatro. Esto se
soluciona realizando una conversin cuando alguna orden lo requiere.
La 2 cuestin no es en s muy grave, entraa el riesgo de poder causar errores debidos
a despistes, pero teniendo claros los diferentes casos basta hacer un cdigo especfico
para las pocas ocasiones en que esto ocurre. Una de estas instrucciones es la de carga
del acumulador (lda), en el 6809 modifica las banderas N,Z y V; sin embargo en el x86
no afecta absolutamente a ninguna. Esto puede solucionarse fcilmente aadiendo una
suma tras la carga: qu valor sumar? Ninguno:
movb
addb
-1(%ebp,%esi),%bh
$0,%bh
De esta forma se fuerza una modificacin del registro de banderas del x86.
Lamentablemente addb tambin cambia el dgito de acarreo y para evitar su
modificacin en el 6809 es necesario filtrar el resultado con operaciones lgicas and y or.
90
91
El mapa de memoria es una regin de 3x64 kilo octetos, cada parte de 64koct contiene
un tipo de informacin: la primera tiene la ROM de la mquina, la segunda la RAM y
la ltima un mapa sobre cmo interpretar cada octeto: un cero indica RAM; un uno,
ROM; y cualquier nmero mayor que dos implica que para acceder a esa posicin hay
que hacer una llamada a una funcin definida por el usuario. Una determinada
estructura contiene los punteros a estas funciones en un orden tal que segn sea el
valor escrito en el mapa de memoria se llamar a una u otra. En Escuela de combate esta
estructura se inicia de la siguiente forma:
static EMUHANDLERS emuh[3] ={
LeePagina,EscribePagina,
LeeVideo,EscribeVideo,
Lee500,Escribe500 };
Esto significa que si se accediese a la posicin 500h, el emulador ejecutar las funciones
que ocupen la tercera posicin (4-1=3) de la estructura; en este caso, las funciones:
Lee500 y Escribe500.
Durante el desarrollo de Escuela de combate, el emulador de Larry Blank demostr ser
un programa rpido, estable y fiable; no se encontr ningn error de programacin ni
comportamiento anmalo durante todo el proceso.
92
La sincrona
Los mquinas de videojuegos no disponan normalmente de reloj interno. El
mecanismo empleado para medir el tiempo consista en contar el nmero de
sincronismos verticales de la imagen. Como cada uno produca una interrupcin,
sabiendo la frecuencia de los mismos y el nmero de interrupciones que haba pasado
se saba el paso del tiempo con suficiente exactitud. El caso ms habitual era el de
monitores a 60 Hz, lo que implica sesenta interrupciones por segundo.
Cuando se emula el juego no se puede tener un control preciso sobre el tiempo pero
tampoco es necesario. Pese a que se sepa exactamente cunto tardara una determinada
instruccin en ejecutarse en el procesador, no tiene utilidad el emularla justo en ese
tiempo. Lo nico que percibe el usuario son las imgenes del juego y la msica del
mismo, slo en estos dos apartados la sincrona es importante.
Nuestra preocupacin es, por lo tanto, dibujar imgenes cada sesentavo de segundo.
Sin embargo esto implica una primera preocupacin: cuntas instrucciones hay que
ejecutar entre pantalla y pantalla? Si llevsemos a cabo una cuenta exhaustiva de los
ciclos de reloj acaecidos en el procesador podramos replantear la pregunta a cuntos
ciclos de reloj han de pasar entre pantalla y pantalla? La respuesta entonces sera
inmediata: el producto de la frecuencia de reloj por el intervalo entre imgenes, as
para un procesador a 1 MHz operando con una pantalla a 60 Hz deberamos de
ejecutar 16,666 ciclos. Este enfoque, aunque riguroso, es poco prctico pues implica
aadir cdigo adicional a la emulacin del procesador que enlentecera la operacin.
Una solucin aproximada es tomar la media de ciclos por instruccin como medida
para ejecutar no un nmero de ciclos sino de instrucciones: por ejemplo, el 6809 tiene
una ejecucin media de una instruccin por cada dos ciclos, luego el intervalo
propuesto es aproximadamente equivalente a 33,333 ciclos.
Lamentablemente la solucin anterior no funciona a la perfeccin produciendo
situaciones en las que el emulador dispara una interrupcin antes de cuenta,
provocando un funcionamiento anmalo que causa retardos en la animacin. La forma
de solventar este problema es operar con exceso: Cuando el bucle del videojuego llega
a la fase de espera no importa cuntas instrucciones se ejecuten, puesto que la accin ya
no avanzar hasta que se dispare una interrupcin.
La solucin final es por tanto, emular entre imgenes un nmero de instrucciones
superior (en torno a un 10%) al nmero de instrucciones ejecutables durante ese tiempo,
basado en el promedio de ciclos por operacin.
Desde un punto de vista bsico: una vez ejecutadas las IPI 33 correspondientes, el
emulador dibuja la pantalla y lee la entrada del teclado; acto seguido el bucle vuelve a
empezar. De ser as, sin embargo, en un ordenador moderno el juego se desplazara a
tal velocidad que sera injugable; y en un equipo lento la accin se vera retardada. Es
necesario incluir un mecanismo de ajuste de la velocidad para no pecar ni por exceso ni
por defecto. En las prximas secciones se estudian los dos mecanismos bsicos de
sincrona.
33
93
34
35
94
}
Esta funcin se ejecutar sesenta veces por segundo automticamente, el sistema
operativo se encargar de ello. Durante el bucle de la emulacin se ejecuta
simplificadamente- lo siguiente:
for(;;)
{
ejecuta( ipi );
irq();
if ( ips_real > ips_ideal )
dibuja_pantalla( ant_munecos );
if ( ips_ideal >= 59 )
{
ips_ideal=0;
ips_real = 0;
}
ips_real++;
}
36 No todos los ciclos son iguales. Las rutinas de optimizacin del vdeo son las mximas
responsables de que unos ciclos sean ms lentos o rpidos que otros.
37 El emulador de G&G
95
Sincronizacin cronometrada
Cuando el equipo emulante es suficientemente rpido se hace necesario buscar una
forma eficaz de sincronizar el proceso de emulacin y pintado de imgenes. Por una
parte, al sobrar tiempo entre uno y otro fotograma, sera recomendable desocupar el
procesador para que el sistema operativo d ese lapso a otros procesos. Por otra parte,
los monitores actuales suelen operar con refrescos muy superiores a 70Hz lo que
ocasiona que la tcnica de sincrona con el retrazado del monitor no funcione;
necesitamos un mecanismo vlido para frecuencias de la pantalla emulada distintas de
la emulante.
El mtodo de sincronizacin cronometrada se basa en cronometrar lo que se tarde en
emular el procesador y dibujar la pantalla para esperar despus hasta que se cumple
un perodo38. Llegado ese momento el ciclo vuelve a empezar.
5,5
100 = 27,5% y el restante 72,5% queda libre para otras tareas.
20
En el caso de que se emulase una mquina a 50 o 70 Hz bastara con cambiar el tiempo
lmite de espera de 16,6ms a 20ms o 14,3ms. Conceptualmente este mtodo es muy
sencillo pero a la hora de realizarlo puede ser laborioso segn la plataforma de
desarrollo ya que el sistema operativo provee habitualmente de medidas del tiempo en
unidades de un milisegundo.
Para el caso de Windows hay un juego de funciones pensadas para aplicaciones
multimedia entre las que se incluyen algunas para sincronizacin precisa.
38
96
97
Cometido
Frecuencia (MHz)
6809
Z80
YM2203 (dos)
Juego
Sonido
Sonido
1.5
3
Memoria
ROM (koct)
32
Tamao
(koct)
16
32
32
16
GG5
GG6
GG7
GG8
GG9
GG10
GG11
GG12
GG13
GG14
GG15
GG16
GG17
32
16
16
16
16
16
16
16
16
16
16
16
16
Descripcin
Caracteres
Memoria de sonido (Z80)
Memoria sin paginar del juego (6809)
Los primeros ocho kilo octetos son
memoria paginada del 6809, los
siguientes ocho kilo octetos no se
paginan.
Memoria paginada del 6809
Juegos 3 y 4 del fondo
Juegos 1 y 2 del fondo
Juegos 3 y 4 del fondo
Juegos 1 y 2 del fondo
Juegos 3 y 4 del fondo
Juegos 1 y 2 del fondo
Animaciones
Animaciones
Animaciones
Animaciones
Animaciones
Animaciones
98
Posicin
(hexadecimal)
0000-1DFF
1E00-1F80
2000-23FF
2400-27FF
2800-2BFF
2C00-2FFF
3000
3002
3800-39FF
3A00
3B08
3B09
3B0A
3B0B
3C00
3E00
4000
6000
8000
Descripcin
ROM asociada
de
39
Dgito 7
2
moneda,
100 ptas.
Dgito 6
1
moneda,
25 ptas.
Dgito 5 Dgito 4
Salto
Disparo
Dgito 3
Arriba
Dgito 2 Dgito 1
Comienzo
del 2
jugador
Abajo
Izquierda
Dgito 0
Comienzo
del 1er
jugador
Derecha
Como en C los ndices de los vectores empiezan desde cero, rom[4] apunta a gg5
99
40
100
Con el dgito quinto puede seleccionarse cualquiera de las dos pginas disponibles, de
256 bloques cada una. Hay diecisis paletas de cuatro colores disponibles para los
caracteres.
Tanto los cdigos de los fondos como sus atributos se componen de cuatro pantallas
que se cierran sobre s mismas cuando se proyectan a travs de la ventana virtual del
juego. Es decir, es el funcionamiento bsico descrito en la seccin de fondos.
Cuando se interpreta el contenido de los fondos hay que tener en cuenta que en esta
mquina concreta, los fondos internamente se indican con su cdigo- girados 90, por
lo que cada incremento de un octeto en la memoria de fondo no indica avanzar en las
abscisas, sino en las ordenadas.
Formato de los octetos de atributos de los fondos
5
4
3
2
1
giro
giro
pgina de ROM
prioridad
paleta
vertical horizontal
7
Los dgitos sexto y sptimo indican cul de los cuatro juegos de fondos disponibles en
las memorias ROM se seleccionarn; en total hay cuatro pginas de 256 bloques.
Cuando el tercer dgito, de prioridad, est marcado significa que el bloque de fondo se
dibuja sobre los objetos. Con los tres dgitos de menor peso pueden seleccionarse ocho
paletas, cada una de ocho colores.
Los objetos mostrables simultneamente en pantalla son 96, cada uno requiere cuatro
octetos cuyo orden es el siguiente: cdigo del objeto, atributos, abscisa y ordenada.
Formato de los octetos de atributos de los objetos
7
6
5
4
3
2
1
0
giro
giro
sin uso
recorte
pgina de ROM
paleta
vertical horizontal conocido horizontal
101
Contenido
paletas de fondo
paletas de objetos
paletas de caracteres
duplicado (?)
Colores
8
16
16
Paletas
8
4
4
102
Interruptores DIP
Esta mquina tena dos microinterruptores DIP que permitan configurar algunas de
las caractersticas del juego.
Uso
ninguno
dificultad
bonificacin
mueble
vidas iniciales
Accin
ninguna
fcil
normal
difcil
dificilsimo
1
X
NO NO
NO SI
SI NO
SI
SI
20.000,
70.000 y
cada 70.000
30.000,
80.000 y
cada 80.000
slo a los
20.000 y a
los 70.000
slo a los
30.000 y a
los 80.000
mesita
de pie
1
2
3
4
NO NO
NO
SI
SI
NO
SI
SI
NO
SI
NO NO
NO SI
SI NO
SI
SI
microinterruptor 1A
La bonificacin es una vida adicional y por tanto est relacionada con la dificultad del
juego. En G&G es habitual haber conseguido 20.000 puntos al terminar la primera fase
y obtener los 70.000 al llegar a la tercera fase; de esa forma el jugador obtiene una
pequea recompensa con sus progresos. Alcanzar los 140.000 puntos mnimos
necesarios para una tercera vida extra exiga un juego muy orientado a puntuar que era
a la par peligroso y aburrido.
En el segundo microinterruptor se define si la pantalla se girar vertical y
horizontalmente para el caso en que la imagen se vea a travs de un reflejo.
Hay adems un microinterruptor que permite operar el equipo en el modo de pruebas
para detectar algunos errores, esto se detallar en el apartado siguiente.
Esta mquina slo permita utilizar una de las dos entradas de monedas instaladas,
para ella se defina la relacin entre nmero de partidas y monedas deseada.
103
Accin
1
2
3
4
5
6
7
8
normal NO
pantalla
invertida SI
normal
NO
funcionamiento
de
SI
pruebas
siempre
SI
sonido
juego
NO
primero
NO
monedero a
usar
segundo
SI
1/1
NO NO NO NO
1/2
NO NO NO SI
1/3
NO NO SI NO
1/4
NO NO SI
SI
1/5
NO SI NO NO
1/6
NO SI NO SI
1/7
NO SI
SI NO
monedas
/
2/1
NO SI
SI
SI
partidas
2/2
SI NO NO NO
2/5
SI NO NO SI
3/1
SI NO SI NO
3/2
SI NO SI
SI
3/4
SI
SI NO NO
4/1
SI
SI NO SI
4/3
SI
SI
SI
SI
microinterruptor 2A
104
El modo de pruebas
Cuando el tcnico activa el modo de pruebas aparece una pantalla de informacin que
sirve para saber el estado de los microinterruptores y para hacer una pruebas mnimas.
Las tablas mostradas en el apartado anterior encuentran su correspondencia aqu y
puede verse fcilmente la correspondencia entre los interruptores y este modo.
Pese a que existen dos lneas de equivalencias entre monedas y partidas slo una de
ellas es ajustable, como se indic anteriormente. El acrnimo ATS significa ATraction
Sound y hace referencia al interruptor de sonido, su funcin es si habr o no sonidos y
msica cuando no est jugando nadie; si los hubiese, serviran para atraer clientes.
Las columnas de ceros bajos los acrnimos 1P y 2P se tornan en unos cuando la palanca
o los botones adecuados se pulsan, de esta forma se puede comprobar su
funcionamiento.
Bajo Sound Code (cdigo de sonido) se encuentra un nmero que puede cambiarse
usando derecha e izquierda, al pulsar el botn de disparo el sonido se reproduce. Esto
sirve para detectar fallos de sonido, el siguiente diagnstico puede aplicarse:
Problema
No se oye ningn sonido
Posible causa
Acciones recomendadas
Fallo grave en el -Comprobar la conexin
altavoces
sistema de audio.
de
los
105
Miscelnea
La comprobacin de las memorias que hace la mquina al arrancar puede saltarse, en
la versin estadounidense de G&G, evitando la llamada a la rutina mediante la
colocacin oportuna de tres operaciones nulas nop. El cdigo del mapefer3 que realiza
esto es:
if (juego == GNG_USA) ram[0x607a] = ram[0x607b] = ram[0x607c] = 0x12; /*nop*/
106
Gryzor
Contenido de los ficheros ROM
Contenido
Fichero
Tipo de EPROM Lugar en la placa41
G-1.ROM
27256 - 32kOct
P5
Cdigo de sonido
G-2.ROM
27512 64kOct
H2
Cdigo de juego
G-3.ROM
27512 64kOct
J2
Cdigo de juego
G-4.R.ROM OM 27512 64kOct
A17
Fondo lejano
G-5.ROM
27512 64kOct
C17
Fondo lejano
G-6.ROM
27512 64kOct
D17
Fondo lejano
G-7.ROM
27512 64kOct
F17
Fondo prximo
G-8.ROM
27512 64kOct
H17
Fondo prximo
G-9.ROM
27512 64kOct
J17
Fondo prximo
G-10.ROM
27512 64kOct
K17
Fondo prximo
G-11.ROM
27512 64kOct
L17
Objetos
G-12.ROM
27512 64kOct
M17
Objetos
G-13.ROM
27512 64kOct
P17
Objetos
G-14.ROM
27512 64kOct
Q17
Objetos
G-15.ROM
27512 64kOct
R17
Objetos
G-16.ROM
27512 64kOct
T17
Objetos
G-17.ROM
27512 64kOct
V17
Objetos
G-18.ROM
27512 64kOct
W17
Objetos
La posicin que ocupa en la placa est descrita en forma de coordenadas. Es muy
habitual nombrar las columnas y las filas en las placas de circuito impreso con letras y
nmeros para filas y columnas, a cada componente se le asigna una combinacin de
ambos y esa referencia se utiliza en las reparaciones cuando se encargan componentes
al fabricante.
Descripcin
Insertar monedas y comenzar
entrada del 1er jugador
entrada del 2 jugador
DIP 0
DIP 1
DIP 2
Contador de monedas
Disparador de interrupciones
Estas ROM se volcaron de una placa Gryzor (Contra) japonesa de contrabando etiquetada
712-47, fueron una aportacin del australiano arcade@zws.com; que tambin ayud durante el
proyecto con fotografas e informacin de primera mano sobre el funcionamiento real del
equipo.
41
107
Registro de autoarranque
Paleta grfica
Memoria RAM, 4 koct
Atributos del fondo 1, lneas 5-25h
Fondo 1, lneas 5-25h
Atributos del fondo 1, lneas 0-5
Fondo 1, lneas 0-5
Objetos
Objetos, Reflejo de 3000-37FF?
Desplace del 2 fondo
Fondo 2, atributos
Fondo 2, bloques
Objetos
Reflejo de 5000-57FF (?)
Registro de paginacin
Memoria paginada
32 koct de ROM, son los superiores de G2.ROM
Descripcin
Comunicacin con la otra UCP
Registro del YM2151, slo lectura
Datos del YM2151, lectura y escritura
RAM
ROM
108
Los objetos se componen de bloques de 16x16 puntos, pero cada uno de estos bloques
se almacena en la ROM como cuatro de 8x8 puntos, cuya codificacin es anloga a la
de los caracteres. Para formar el bloque de 16x16 a partir de los de 8x8 hay que seguir
el siguiente orden: en la memoria ROM los cuatro bloques aparecen como ABCD, si se
reconstruyen se puede formar el bloque:
A B
C D
Pero ste est girado 90 grados, que es lo que necesitaba la circuitera de Gryzor. Para
la emulacin necesitamos que el bloque est horizontal, luego lo giramos 90
quedando:
C A
D B
42
109
110
El segundo fondo
ste fondo est en la posicin 4400h (4000h para los atributos) y parece utilizar siempre
la misma paleta. Ocupa un rea de 256x256, en Grytra se pinta de la siguiente manera
attr = (attr&0xf8)>>3;
aux = (attr&0x10) >> 4;
attr = ((attr<<1)+aux)&0x1f;
pon_bloque_bruto( fondo[0], ram[explo]+/*bloque[attr]*/(attr<<8), x<<3,
y<<3, 6<<4 );
Los objetos
Los objetos en Gryzor ocupan cuatro zonas de memoria distintas, stas son: 3000h,
3800h, 5000h y 5800h; sin embargo parece que unas son una imagen de las otras luego
basta con pintar dos de ellas. El emulador programado dibuja las zonas 3800h y 5000h.
Estas zonas se componen de estructuras de cinco octetos donde el antepenltimo y el
penltimo son las coordenas; abscisas y ordenadas respectivamente, y los dos primeros
los atributos. La posicin en la memoria ROM del bloque a dibujar se obtiene a partir
de la siguiente frmula:
attr = (ram[explo+1]&0x7)<<8;
bloque = (ram[explo]+attr)<<2;
Por ltimo, si el dgito 6 del quinto octeto est activado hay que sumar 4096 al nmero
de bloque:
if ( ram[ explo+4 ] &0x40 ) bloque+=1024*4;
Por ltimo Gryzor tiene una peculiaridad: hay un determinado dgito que, caso de estar
activo, nos indica que hay que dibujar un objeto no de 16x16 sino de 32x32, en ese caso
los nmeros de bloque restantes son consecutivos.
La paleta grfica
Hay ocho paletas grficas sitas en 0C00h, cada una de 32 octetos de longitud. Cada
color est compuesto por tres primarios (rojo, verde y azul) de cinco dgitos cada uno
(25*3=2048 colores). Vistos en memoria los colores estn escritos en parejas de dos
111
ram[con+0xc00+paleta*32];
= aux&0x1f;
= (aux&0xE0)>>5;
ram[con+0xc01+paleta*32];
= (aux&0x7c)>>2;
|= (aux&0x3)<<3;
Octeto inferior,
ah estn el rojo
y parte del verde
en el octeto superior estn el azul y el resto
del verde
Como la paleta de la VGA trabaja con colores de 6 dgitos, es necesario aadir una cifra
adicional al color. Lo ideal sera hacer una transformacin lineal multiplicando por 63
y dividiendo por 31, pero es ms rpido hacer sencillamente un desplazamiento de una
posicin a la izquierda; el error cometido es muy pequeo y bsicamente en la
luminancia de la imagen:
rgb.r <<= 1;
rgb.g <<= 1;
rgb.b <<= 1;
112
Interruptores DIP
Primer microinterruptor
Uso
Accin
1/1
1/3
1/4
1/5
1/6
1/7
primer monedero
2/1
2/3
2/5
3/1
3/2
3/4
4/1
4/3
precio
gratis
1/1
1/2
1/3
1/4
1/5
1/6
1/7
segundo monedero
2/1
2/3
2/5
3/1
3/2
3/4
4/1
4/3
Sin uso
Invlido
1
NO
NO
NO
NO
NO
NO
NO
NO
SI
SI
SI
SI
SI
SI
SI
SI
2
NO
NO
NO
NO
SI
SI
SI
SI
NO
NO
NO
NO
SI
SI
SI
SI
3
NO
NO
SI
SI
NO
NO
SI
SI
NO
NO
SI
SI
NO
NO
SI
SI
4
NO
SI
NO
SI
NO
SI
NO
SI
NO
SI
NO
SI
NO
SI
NO
SI
NO
NO
NO
NO
NO
NO
NO
NO
SI
SI
SI
SI
SI
SI
SI
SI
NO
NO
NO
NO
SI
SI
SI
SI
NO
NO
NO
NO
SI
SI
SI
SI
NO
NO
SI
SI
NO
NO
SI
SI
NO
NO
SI
SI
NO
NO
SI
SI
NO
SI
NO
SI
NO
SI
NO
SI
NO
SI
NO
SI
NO
SI
NO
SI
113
Bonificacin
Dificultad
Sonido de
captacin
Accin
2
3
5
7
a los 30.000 y
cada 70.000
a los 40.000 y
cada 80.000
slo a los 40.000
slo a los 50.000
fcil
normal
difcil
dificilsimo
NO
SI
1
NO
NO
SI
SI
2
NO
SI
NO
SI
NO
NO
NO
SI
SI
SI
NO
SI
NO
NO
SI
SI
NO
SI
NO
SI
Tercer microinterruptor
Uso
Accin
1 2 3
4 5 6 7 8
Giro de la pantalla normal
NO
invertido SI
normal
NO
funcionamiento
SI
pruebas
estreo
NO
tipo de sonido
SI
mono
La explicacin de estas opciones es la misma que en el caso del G&G. La configuracin
por defecto del equipo era: una moneda por partida ambos monederos, tres vidas con
bono a los 30.000 y cada 70.000 puntos, dificultad normal, sin girar la pantalla, modo
de juego y sonido estreo43.
43
114
El modo de pruebas
Gryzor incluye un modo de pruebas ms completo que el de G&G, consta de seis
pantallas por las cuales se navega pulsando simultneamente 1P y 2P.
1. Prueba de entradas
2. Prueba de contadores
3. Interruptores DIP
5. Prueba de color
6. Prueba de sonido
115
Miscelnea
Al igual que en el caso de G&G, es posible saltarse las rutinas iniciales de verificacin
del equipo para acelerar el arranque de la mquina. El cdigo empleado en Grytra es:
/* parche para saltarse la comprobacin de la RAM/ROM */
ram[ 0x800a] = 0x63;
ram[ 0x800b] = 0xe7;
116
Combat School
Combat School funcionaba en una placa con dos procesadores: un 6809 para el juego,
que funcionaba a 3MHz; y un Z80 para el sonido, a 15MHz. El responsable de la
msica era el integrado de Yamaha YM2203 y el encargado de reproducir las voces
digitalizadas era el UPD7759.
117
Longitud
(octetos)
4
1
1
256
4608 (?)
4096
4096
16384
32768
Descripcin
Lmite de los objetos44
Orden de escritura (prioridad) de los grficos
Paginacin de la ROM y seleccin del circuito grfico
Paleta grfica
Memoria RAM
Circuitos grficos, fondos
Circuitos grficos, objetos
Memoria paginada, registros de E/S y de vdeo
Memoria ROM
En la posicin 500h hay un registro de ocho dgitos que controla qu pgina de ROM
est seleccionada y qu circuito grfico (de los dos disponibles) est seleccionado.
Registro 500h
Dgito 7 Dgito 6 Dgito 5 Dgito 4 Dgito 3 Dgito 2 Dgito 1 Dgito 0
Circuito
Pgina de ROM seleccionada
grfico
La mquina tiene dos circuitos grficos de 8192 octetos de longitud situados en la
posicin 2000h, cada uno de ellos es capaz de dibujar fondos y objetos sobre ellos.
Las pginas no siguen un orden natural ya que hay una algn tipo de codificacin en el
nmero que se escribe en 500h; de hecho, hay 32 posibles pginas segn 500h pero slo
18 de ellas son reales.
Nmero
de pgina
00
01
10
12
14
16
18
1A
1C
1E
44
Fichero
Posicin en el fichero
ROM
Combat.002
0
Combat.002
4000h
Combat.003
0
Combat.003
2000h
Combat.003
4000h
Combat.003
6000h
Combat.004
0
Combat.004
2000h
Combat.004
4000h
Combat.004
6000h
118
Combat.002
4000h
119
Los objetos
Los objetos, bloques de 16x16 puntos, estn mapeados en la zona 3000-3FFFh. All una
estructura de cinco octetos de longitud contiene la informacin sobre qu, dnde y
cmo pintarlos.
Octeto 0
Nmero de
bloque
Octeto 1
Octeto 2
Octeto 3
Octeto 4
Abscisa
Ordenada
Atributos
paleta
El nmero completo del bloque a pintar, una vez colocadas todas las ROM linealmente
en memoria se obtiene mezclando la informacin de los atributos con el nmero dado
en el primer octeto:
int pagina = (color & 0x03) | ((atributos & 0x40) >> 4);
bloque = ((bloque & 0x02) << 1) | ((bloque & 0x04) >> 1) | (bloque & (~6));
bloque += 256*pagina;
Como vemos, es necesario desenredar un cierto galimatas con los dgitos binarios para
poder obtener un nmero de bloque lineal.
Las coordenadas requieren tambin una pequea transformacin antes de ser
utilizables:
unsigned x = contador[2] - 71 + (atributos & 0x01)*256;
unsigned y = 242 - contador[1];
Las ordenadas se almacenan contando desde abajo, para invertirlas basta restarlas de la
altura de la pantalla (242 puntos). Las abscisas tambin estn tomadas al revs, pero
adems falta el dgito de mayor peso que se obtiene de los atributos.
El quinto dgito de los atributos (mscara: 10h) indica si hay que girar horizontalmente
el objeto al pintarlo.
120
El modo de pruebas
Las pruebas de Combat School son muy parecidas a las de Gryzor, por tanto slo se
explicarn las diferencias, remitimos a la seccin sobre Gryzor para una explicacin
ms detallada.
1. Ortogonalidad de la pantalla
2. Prueba de sonido
3. Prueba de color
6. Interruptores DIP
121
Miscelnea
Conexin de una palanca normal
Como ya se ha comentado anteriormente, Combat School funcionaba con una especie de
semiesfera que dotaba al jugador de diecisis direcciones posibles de movimiento
frente a las ocho de una palanca normal. El requisito de la semiesfera limitaba el uso de
la placa con muebles convencionales (distintos al original de Konami) sin embargo
haba una forma de utilizar esta placa con una palanca normal.
122
Los emuladores
En este ltimo apartado presentaremos detalladamente el resultado del proyecto: los
emuladores de las tres mquinas recreativas estudiadas, Ghosts & Goblins, Gryzor y
Combat School.
Plataforma de desarrollo
Se evaluaron varias alternativas: Turbo C, ensamblador 8086, ensamblador 80386,
Watcom C/C++, Borland C 4.5 y el gratuito GCC. La decisin final fue GCC y los
motivos fueron:
La gran ventaja de RHIDE consiste en que la interfaz que presenta est calcada de la
del Turbo Pascal y el Turbo C por lo que el uso es inmediato si se tiene experiencia en
alguna de las herramientas de Borland.
El sistema an no estaba completo pues si se quera evitar direccionar directamente la
memoria de vdeo del PC, con el engorro que ello conlleva, haca falta una biblioteca
grfica. La eleccin fue Allegro, biblioteca de 32 dgitos para Gcc, de sencillo manejo y
gran versatilidad.
As que Rhide se utiliz para escribir el proyecto, Gcc para compilarlo tanto el cdigo
en C como el cdigo de ensamblador incrustado y Allegro como interfaz con el sistema
grfico del PC.
El compilador de C gnu en su versin para PC puede descargarse de
http://www.delorie.com/djgpp
Gcc es mucho ms popular en Linux as que casi todos los entornos disponibles son para este
sistema operativo.
46 El nombre RHIDE, est formado por las iniciales del autor ms el acrnimo IDE (Integrated
Development Enviroment, entorno de desarrollo integrado)
45
124
Funcin main
125
Preparacin
Bucle de la emulacin
126
127
Bucle de emulacin
Si el juego est pausado slo se comprueba el
teclado y se redibuja la pantalla. No se avanza
la simulacin.
Se
ejecutan
IPI
(Instrucciones Por
Interrupcin) instrucciones y se dispara una
interrupcin despus.
El control de la velocidad se realiza mediante
promediado
128
OpIlegal
void ilegalC()
{
printf("Op ilegal = %X",ram[pc-1]);
vuelca_regs();
exit( ram[pc-1] );
}
Esta sencilla funcin se ejecutar cuando se encuentre una instruccin del 6809 sin
emular. En la actualidad, con una emulacin del procesador acabada y fiable, est
funcin no es llamada jams, sin embargo, durante el desarrollo inicial del emulador
fue muy til para detectar errores
Inicia6809
Esta rutina est programada en ensamblador (fichero 6809.s) y su objetivo es preparar
las tablas de memoria que se utilizan como ndice de salto para las operaciones
emuladas.
.align 4
_Inicia6809:.globl _Inicia6809
pushl
$0x10000
call
_malloc
add
$4,%esp
cmpl
$0,%eax
jne
reser
ret
reser:
movl
%eax,_ram
movl
%eax,%edi
#Rellena la
RAM con ceros
movl
$0x10000/4,%ecx
movl
$0,%eax
rep
stosl
# operaciones
movl
$256,%ecx
lea
opIlegal,%eax
lea
_ops,%edi
rep
stosl
.../...
La rutina contina rellenando ahora las tablas con los valores de las operaciones
emuladas. Los cdigos de operacin que no estn reconocidos por el programa
quedarn con la llamada a opIlegal, establecida por defecto.
Cuando todas las tablas estn completadas, la emulacin del procesador est a punto y
puede comenzar a ejecutar instrucciones. Hay ms informacin sobre este proceso en la
seccin dedicada al procesador.
129
130
Las que tienen efecto en la mquina simulada: los cursores que mueven el
personaje, la tecla 3 que inserta monedas
Las que actan en el emulador en s: como la P para pausa y la tecla Esc para
salir del programa
La variable altura controla que cada mensaje se escriba sin mezclarse con el anterior.
131
Cdigo de dibuja_pantalla
Existen dos formas de calcular la paleta grfica del PC a partir de la original. Cada
color primario puede tener diecisis niveles (del 0 al 15) o equivalentemente, cada color
est codificado en un cuarteto. Para pasar el color a PC es necesario que ocupe seis
dgitos (64 niveles). La funcin PaletaR (R de rpida) realiza la conversin
multiplicando por cuatro el color original desplazando dos dgitos a la izquierda. Esta
operacin es muy rpida pero tiene el inconveniente de que los resultados son
inexactos; por ejemplo el color de mxima intensidad originalmente es el 1111b, tras la
conversin ste queda como 111100b que en decimal equivale a 60, un 666% menor de
lo que debera ser (111111b 64). As todos los colores presentan un pequeo error que
slo puede corregirse escalando el valor adecuadamente: multiplicando por 63 y
dividiendo el resultado por 15. Como esta operacin es ms lenta y el objetivo del
emulador era la rapidez se dej como una opcin: el jugador puede elegir qu paleta
ver pulsando la tecla espacio. Alternando la paleta durante el juego se puede apreciar la
diferencia que es ms notable en cuanto a luminancia que en cuanto a crominancia.
Fondo y dibuja_fondo
Esta pareja de funciones son las responsables de construir el fondo virtual (Fondo) y de
copiar la ventana activa a la pantalla (dibuja_fondo). No vamos a detallar el cdigo de
Fondo, pues es demasiado extenso, pero s vamos a hacer notar su principal
optimizacin.
Dado que Fondo ha de construir la imagen virtual formando un mosaico con los
bloques de 8x8 que componen los grficos de la mquina; puede comprobar
rpidamente, sin ms que comparar el cdigo del bloque ya pintado con el cdigo que
la mquina pide en el nuevo fotograma, si ese cuadrado ha cambiado desde la ltima
vez que se pint. Si no hubiese cambiado no es necesario volver a pintarlo y por lo
tanto se ahorra la operacin de copiar 64 octetos. En la prctica, la mquina slo
renueva el fondo virtual totalmente al cambiar de nivel; durante el juego el fondo se
actualiza muy lentamente y se emplean las variables de desplace para pintar
nicamente el rea visible que est lista.
132
fondo_virtual,bmp,
fondo_virtual,bmp,
fondo_virtual,bmp,
fondo_virtual,bmp,
sup. izq.
sup. der.
inf. der.
inf. izq.
La funcin blit pertenece a la biblioteca grfica Allegro y sirve para copiar rectngulos
entre imgenes.
Esta vez no hemos optado por optimizar la copia. Es posible, una vez ms, controlar
qu partes de la imagen destino han cambiado desde la ltima vez y omitirlas del
proceso; sin embargo, este caso es bastante ms complicado que el anterior:
El fondo, aun siendo el mismo, ha sido emborronado por los personajes que se
mueven sobre l, luego los bloques afectados deberan ser copiados otra vez.
Cuando la pantalla se desplaza los bloques, pese a ser los mismos, ya no
ocupan la misma posicin, as que hay que volver a pintarlos.
Si quisiramos optimizar la copia habra que resolver estos dos problemas. El primero
es sencillo y su solucin se basa en tener una matriz que indica que bloques han sido
afectados por los objetos o caracteres. El segundo problema es ms complicado aunque
la solucin es muy elegante: en las tarjetas grficas VGA puede reproducirse el mismo
esquema de gran pantalla virtual y ventana visible. Habra que utilizar toda la
memoria grfica de una VGA convencional (1Moct) para dibujar ah todo el fondo
virtual, luego puede escogerse qu regin visualizar a travs de unos registros internos
de la VGA. Se trata pues, de repetir el enfoque de la mquina original. Esta
programacin es ms complicada que la actual aunque es la que ofrece el mejor
rendimiento. No se lleg a realizar porque la velocidad alcanzada por el emulador era
ya suficiente.
133
Fichero
Descripcin
destruye_sonidos
gng.c
dibuja_fondo
dibuja_pantalla
segn las variables de desplace, copia una ventana desde el fondo virtual
gng_dir.c al real
gng.c
interpreta la memoria grfica de la mquina para dibujar la pantalla.
Sincronizacin con el trazado vertical
6809c.c
gng.c
irq
libera_rom
6809c.c
gng.c
main
gng.c
mensaje
gng.c
ilegalC
imprime_error
muestra_mensajes gng.c
prepara_memoria
prepara_sonido
presentacin
gng.c
salva
teclado
gng_dir.c salva la memoria RAM del juego para poder continuar la partida ms tarde
gng.c
lee el teclado e informa a la mquina
temporizador
gng.c
toca_sonidos
gng.c
vuelca_regs
6809c.c
134
Portada de DR
Juego (DR)
Makaimura
135
Plataforma de desarrollo
Dado que este emulador se escribi poco tiempo despus de acabar mapefer3, la
plataforma escogida fue la misma: el compilador gcc, el entorno Rhide y la biblioteca
grfica Allegro. A ello se una el ya veterano emulador del 6809 programado para
mapefer3.
En esta ocasin no haba ningn dato sobre el funcionamiento del equipo as que hubo
que investigarlo todo. Eso convirti al emulador en un diseo mixto: analizador y
emulador, a la vez que favoreci el desarrollo pero dio lugar a un programa lento e
ineficiente para jugar, al contrario que mapefer3 que era rapidsimo.
136
muestra_mapa
Esta funcin imprime el vector mapa, que contiene la informacin sobre las posiciones
de memoria que han sido accedidas durante la emulacin y sobre el modo del acceso:
lectura, escritura o ambas.
salva y carga
Estas funciones, tambin disponibles en mapefer3, vuelcan la memoria virtual a un
fichero binario y viceversa. Sirven para almacenar el estado del juego y poder as
continuar la partida ms tarde.
muestra_muecos
Durante la investigacin es preciso descifrar el formato de la memoria de objetos. Esta
funcin vuelca esa memoria para poder evaluarla en un momento dado o ver cmo se
modifica durante el transcurso del juego.
137
Plataforma de desarrollo
Para aumentar el inters en la programacin se decidi utilizar Microsoft Visual C++ 5.0
comprando una licencia de estudiante por unos 100 euros, dando as el salto a Windows.
Esto tuvo grandes repercusiones:
el antiguo emulador del 6809 dejaba de ser til, puesto que era difcil
ensamblarlo para Win32, se aprovech para la ocasin un mdulo
preensamblado llamado A6809.obj y desarrollado por Larry Bank para simular
el procesador.
la biblioteca grfica usada anteriormente: Allegro, no funcionaba con Windows
as que tuvimos que utilizar las aun imberbes DirectX para toda la gestin
grfica. Esto aada una nueva dificultad, ya que el modelo de programacin de
DirectX basado en COM47, no nos era familiar en absoluto.
el mero hecho de programar para Windows hizo sencillo dotar al programa de
una interfaz de usuario ms amigable, por lo que se invirti ms tiempo en ella
que anteriormente.
COM es una tecnologa de Microsoft basada en dotar a los programas de interfaces a travs
de las cuales se puedan comunicar entre s. COM es la base de, por ejemplo, los objetos ActiveX,
la tecnologa OLE, de DirectX y del acceso a datos OLEdB.
47
138
Bucle de mensajes
if ( Arranca() != 0 )
{
MessageBox(
NULL,"No
fatal",MB_ICONEXCLAMATION | IDOK
return 0;
}
if ( ArrancaGraficos() != 0 )
{
MessageBox(
NULL,"No
fatal",MB_ICONEXCLAMATION | IDOK
return 0;
}
se
);
encuentran
se
);
encuentran
las
las
ROM
ROM
1-4","Error
5-20","Error
Durante el arranque es preciso leer las memorias ROM, proceso que naturalmente
puede fallar y cuyo error causa el fin del programa. Estas funciones sern explicadas
posteriormente.
Apaga();
ApagaGraficos();
Interfaz para el Programador de Aplicaciones. Son las llamadas al sistema de bajo nivel que
prove Windows
48
139
=
=
=
=
CargaROM(
CargaROM(
CargaROM(
CargaROM(
"roms\\combat.001");
"roms\\combat.002");
"roms\\combat.003");
"roms\\combat.004");
El mapa del procesador hay que especificarlo como aqu se indica, la explicacin de este
procedimiento se encuentra en la seccin del 6809.
grficos
reinicia el procesador:
ARESET6809(pMem6809, ®s6809 );
retardo
for(i=0;i<32;i++ )
pPagina[i] = pROM[1]; // para no provocar ningn error
for( i=0;i<2;i++)
pPagina[0x0+i] = pROM[1]+i*2*0x2000;
for( i=0;i<8;i+=2)
{
pPagina[0x10+i] = pROM[2]+i*0x2000;
pPagina[0x18+i] = pROM[3]+i*0x2000;
}
pPagina[1][0x6145-0x4000]=0x39; // para evitar la rutina
de
pPagina[0x1f] = pPagina[0x1];
/* fin */
iError = 0;
}
else iError = 1;
return iError;
140
pROM[4]=CargaROM("roms\\combat.005");
/
pROM[19]=CargaROM("roms\\combat.020");
for ( i = 4; i<20; i++ )
if ( !pROM[i] ) return 1; // error
ancho y alto
biInfo.biWidth= 256;
biInfo.biHeight = -256;
biInfo.biPlanes = 1;
biInfo.biBitCount = 8; // 256 colores
biInfo.biSizeImage = 256*256;
biInfo.biClrUsed = 128;
Ahora se hacen llamadas a Decodifica que hace lo propio con los grficos adaptndolos a un
formato manejable por el programa.
for(i=0;i<4;i++) Decodifica(i); // 0,1 => caracteres del fondo; 2 y 3
=>objetos
memset( pPantalla, 0, 256*256 ); // limpia el fondo
return 0; // todo bien.
}
WindowFunc
Esta funcin maneja el flujo del proceso respondiendo a los eventos de Windows, por
claridad se omite parte del cdigo para destacar lo importante.
Windows 95 llama a esta funcin que recibe mensajes de la cola de mensajes.
LRESULT CALLBACK WindowFunc( HWND hwnd,UINT message, WPARAM wParam, LPARAM
lParam )
{
cuando se crea la ventana se inicia la hebra que procesa la emulacin del procesador.
141
CreateThread(
NULL,0,Emula6809,(LPVOID)hwnd,0,
&Hebra6809 );
.../...
El evento hEmula indica si la hebra del procesador ha de esperarse o puede seguir con su
labor
hEmula = CreateEvent( NULL, FALSE, TRUE, "Emula" );
.../...
ConfiguraTeclado( &cfgTeclas );
/* configura la paleta, esto es diferente con DirectX */
/* Promediado de la velocidad */
ips.tiempo0 = timeGetTime();
ips.pintadas=0;
break;
case WM_PAINT:
Aqu se pinta la pantalla cada 16ms, esto se hace en dos pasos: primero en una imagen virtual
y luego copindola al dispositivo grfico que el usuario puede ver.
hdc = BeginPaint( hwnd, &ps );
PintaPantalla();
if ( SetDIBitsToDevice( hdc,
0,0, // coordenadas destino
255, 240,
0,0, // coordenadas origen
16, 240, // inicio y final de las lneas
pPantalla, pbiInfo, DIB_RGB_COLORS ) == 0 )
{
MessageBox( hwnd, "Error al volcar la pantalla","",IDOK );
PostQuitMessage(1);
}
EndPaint( hwnd, &ps );
.../...
break;
142
Teclado
El teclado es configurable a travs de la estructura STeclas. El cdigo de la tecla leda
por Windows se compara con los valores de dicha estructura y la cifra adecuada de la
memoria del 6809 se cambia consecuentemente. Para hacer ms legible el cdigo se ha
utilizado una macro.
void Teclado(struct STeclas *sTeclas, unsigned char ucTeclas[256])
{
static unsigned char uc4400=0xff, uc4401=0xff, uc4402=0xff, uc4403=0xff;
#define TECLA( a,b,c ) if( ucTeclas[a] ) b &= ~c; else b |= c;
// Echar monedas
TECLA( sTeclas->ucMoneda1, uc4400, 8 );
TECLA( sTeclas->ucMoneda2, uc4400, 0x10 );
// Comenzar la partida
TECLA( sTeclas->uc1P, uc4400, 4 );
TECLA( sTeclas->uc2P, uc4400, 0x80 );
// controles del primer jugador
TECLA( sTeclas->arriba[0], uc4401, 0x80 );
TECLA( sTeclas->abajo[0] , uc4401, 0x40 );
TECLA( sTeclas->izquierda[0], uc4401, 0x20 );
TECLA( sTeclas->derecha[0], uc4401, 0x10 );
TECLA( sTeclas->saltar[0], uc4400, 0x2 );
TECLA( sTeclas->correr[0], uc4400, 0x1 );
// controles del segundo jugador
TECLA( sTeclas->arriba[1], uc4401, 0x8 );
TECLA( sTeclas->abajo[1] , uc4401, 0x4 );
TECLA( sTeclas->izquierda[1], uc4401, 0x2 );
TECLA( sTeclas->derecha[1], uc4401, 0x1 );
TECLA( sTeclas->saltar[1], uc4400, 0x40 );
TECLA( sTeclas->correr[1], uc4400, 0x20 );
ucPuerto[0] = uc4400; // asigna el valor
ucPuerto[1] = uc4401;
ucPuerto[2] = uc4402;
ucPuerto[3] = uc4403;
}
143
Juego
Mapefer3 Ghosts&Goblins
Grytra
Escuela
de
combate
Gryzor/Contra
Combat School
Velocidad (%)
Fidelidad
486DX PentiumIII
de los
100MHz 600 MHz
colores
Objetos
grficos
Dispositivos
de entrada
Falta la
prioridad
de
Perfectos
fondos
sobre
objetos
Todos, el
usuario
puede elegir
la
configuracin
de los DIP
Palancas
bien, slo son
configurables
algunos DIP
100
100
60
100
Faltan
algunos Perfectos
parpadeos
100
Las
Palancas
regiones
Faltan
lmites de bien, slo son
algunos Perfectos
la pantalla configurables
parpadeos
son
algunos DIP
mejorables
100
Perfecta
Fondos
grficos
Perfectos
144
145
Bibliografa
Videogames on Alternative Monitors FAQ, Jonathan Dawes, jond@videologic.com
Devastators, Instruction Manual, Konami, 1988
Contra, Instruction Manual, Konami, 1987
YM2151 FM Operator Type-M, Yamaha Corporation, 1991
YM3012 2-Channel Serial Input Floating D/A Converter, Yamaha Corporation, 1992
YM3014B Serial Input Floating D/A Converter, Yamaha Corporation, 1994
Ms Pacman Parts and Operating Manual, Midways/Namco, 1982
Arcade Emulation How-To, Michael Adcock, adcock@menudo.uh.edu
146
Y|| vt
Este documento fue editado durante el verano de 2002, en Lmeri (Irlanda)
y
se remat en diciembre del mismo ao en Valencia (Espaa)
147