ZXPP, clon de Spectrum en una Papilio Pro
Moderador: Fundadores
- Kyp
- Hermano de Lucifer
- Mensajes: 3391
- Registrado: 30 Sep 2013, 14:54
- Ubicación: Madrid
- Has thanked: 29 times
- Been thanked: 157 times
ZXPP, clon de Spectrum en una Papilio Pro
¿Otro clon de Spectrum basado en una FPGA? Resulta que cuando empecé a oír hablar de las FPGAs supe que necesitaba una y tras investigar un poco me decidí por la Papilio Pro de Gadget Factory a la que añadí una Arcade Megawing. Tras un tiempo haciendo cosillas con esta placa probablemente no sea la mejor opción, pero eso es otra historia.
La placa de desarrollo:
http://papilio.gadgetfactory.net/index. ... PapilioPro
La placa de conectores:
http://papilio.gadgetfactory.net/index. ... deMegaWing
El caso es que creo que la gracia de todo esto es hacérselo uno mismo así que me he puesto manos a la obra y esto es lo que ha salido.
La placa de desarrollo:
http://papilio.gadgetfactory.net/index. ... PapilioPro
La placa de conectores:
http://papilio.gadgetfactory.net/index. ... deMegaWing
El caso es que creo que la gracia de todo esto es hacérselo uno mismo así que me he puesto manos a la obra y esto es lo que ha salido.
- flopping
- Fundador
- Mensajes: 9973
- Registrado: 29 Mar 2013, 15:26
- Ubicación: Valencia
- Been thanked: 124 times
- Contactar:
Re: ZXPP, clon de Spectrum en una Papilio Pro
Acaba el post, que nos estas dejando con los dientes largo, jajajaajaja
No me hago responsable de mis post pues estan escritos bajo la influencia del alcohol y drogas psicotropicas, por la esquizofrenia paranoide.
(C) 1982-2024, 42 años de ZX Spectrum.
http://www.va-de-retro.com/ un foro "diferente".
Mi juego, que puedes descargar desde aqui
(C) 1982-2024, 42 años de ZX Spectrum.
http://www.va-de-retro.com/ un foro "diferente".
Mi juego, que puedes descargar desde aqui
- Kyp
- Hermano de Lucifer
- Mensajes: 3391
- Registrado: 30 Sep 2013, 14:54
- Ubicación: Madrid
- Has thanked: 29 times
- Been thanked: 157 times
Re: ZXPP, clon de Spectrum en una Papilio Pro
Paciencia, que no es algo que se cuenta en un solo mensaje
- Kyp
- Hermano de Lucifer
- Mensajes: 3391
- Registrado: 30 Sep 2013, 14:54
- Ubicación: Madrid
- Has thanked: 29 times
- Been thanked: 157 times
Re: ZXPP, clon de Spectrum en una Papilio Pro
Paso 0: notas preliminares
La herramienta para crear los diseños que voy a usar es el "ISE Design Suite 14.7" la que facilita gratuitamente Xilinx, el fabricante de la FPGA. No es que sea el mejor IDE del mundo pero hace su trabajo (aunque es desesperadamente lento). Tampoco se le pueden poner muchas pegas porque, como digo, es gratuito. Existe otra Suite que supongo será mejor pero que es de pago (y bastante cara por cierto).
Voy a asumir que se tiene un cierto manejo del IDE, si alguien se atreve a meterse en el lío de seguir mis pasos aquí me tiene para resolver dudas.
Una nota importante, no pretendo hacer un clon 100% exacto del Spectrum. Me voy a tomar ciertas libertades, las más importantes son que tendrá salida VGA y que no tendrá contención (o mejor dicho arbitraje) de memoria.
Ahh, se me olvidaba. De los dos lenguajes más comunes que se usan para diseñar con FPGAs, VHDL y Verilog, voy a usar VHDL. Más que nada por que encontré antes un buen tutorial de este lenguaje. La verdad es que, si lo piensas, en el fondo son muy parecidos, simplemente se escriben las cosas de distinta forma.
La herramienta para crear los diseños que voy a usar es el "ISE Design Suite 14.7" la que facilita gratuitamente Xilinx, el fabricante de la FPGA. No es que sea el mejor IDE del mundo pero hace su trabajo (aunque es desesperadamente lento). Tampoco se le pueden poner muchas pegas porque, como digo, es gratuito. Existe otra Suite que supongo será mejor pero que es de pago (y bastante cara por cierto).
Voy a asumir que se tiene un cierto manejo del IDE, si alguien se atreve a meterse en el lío de seguir mis pasos aquí me tiene para resolver dudas.
Una nota importante, no pretendo hacer un clon 100% exacto del Spectrum. Me voy a tomar ciertas libertades, las más importantes son que tendrá salida VGA y que no tendrá contención (o mejor dicho arbitraje) de memoria.
Ahh, se me olvidaba. De los dos lenguajes más comunes que se usan para diseñar con FPGAs, VHDL y Verilog, voy a usar VHDL. Más que nada por que encontré antes un buen tutorial de este lenguaje. La verdad es que, si lo piensas, en el fondo son muy parecidos, simplemente se escriben las cosas de distinta forma.
- antoniovillena
- Demonio segundo orden
- Mensajes: 1596
- Registrado: 02 Abr 2013, 19:06
- Been thanked: 1 time
Re: ZXPP, clon de Spectrum en una Papilio Pro
De momento puedes portar el código fuente de McLeod para el ZX-Uno, que hasta la fecha es la síntesis FPGA más fidedigna (y completa) que existe para ZX Spectrum. Todo el código está en el repositorio oficial:
http://www.atc.us.es/svn/zxuno/
Usuario: guest
Contraseña: zxuno
Por otro lado hay versiones más modernas de estas placas, en concreto la Papilio DUO-512Kb
http://www.seeedstudio.com/depot/Papili ... cPath=6_10
Con su placa de periféricos
http://www.seeedstudio.com/depot/Classi ... cPath=6_10
http://www.atc.us.es/svn/zxuno/
Usuario: guest
Contraseña: zxuno
Por otro lado hay versiones más modernas de estas placas, en concreto la Papilio DUO-512Kb
http://www.seeedstudio.com/depot/Papili ... cPath=6_10
Con su placa de periféricos
http://www.seeedstudio.com/depot/Classi ... cPath=6_10
- Kyp
- Hermano de Lucifer
- Mensajes: 3391
- Registrado: 30 Sep 2013, 14:54
- Ubicación: Madrid
- Has thanked: 29 times
- Been thanked: 157 times
Re: ZXPP, clon de Spectrum en una Papilio Pro
Hay una diferencia insalvable, al menos por el momento, entre el ZX-Uno y la Papilio Pro y es la RAM. Vosotros, con muy buen criterio, usáis SRAM, pero mi placa lleva SDRAM. La diferencia es bastante notable. Mientras que con la SRAM el acceso es tan sencillo como meter una dirección en un bus y leerlo/escribirlo al cabo de un instante en el bus de datos, con la SDRAM hay que enviar comandos tales como decir cuantas palabras vas a leer, de que banco, mandar el comando de lectura, esperar un número variable de ciclos para que el dato esté disponible... entretanto mandar comandos de refresco... un lio vamos.antoniovillena escribió:De momento puedes portar el código fuente de McLeod para el ZX-Uno, que hasta la fecha es la síntesis FPGA más fidedigna (y completa) que existe para ZX Spectrum. Todo el código está en el repositorio oficial
De momento he usado la BRAM de la FPGA. Tiene justo los 64K necesarios para el clon. Además se puede configurar como RAM de doble puerto, ideal para hacer la RAM baja (asi sí, sin contención, aunque ya he visto como hace McLeod para simularla e igual me animo).
De todas formas esto es un ejercicio mio para aprender a usar las FPGAs. Nada más. El ZX-Uno va mucho más allá y seguro que compro uno cuando esté listo. He dudado mucho en pedir un prototipo pero así me obligo a hacerlo yo mismo.
Por otra parte, el código de McLeod me ha venido muy bien como fuente de inspiración (o copia casi directa en algunos casos)
Por cierto que ya tengo un clon funcional a falta de que compre un conector DB9 para cargar de cinta. De momento he tirado de tus ROMs de juegos y al menos el Manic Miner funciona bien. Y las ROMs de test tampoco dan errores
Si, esta es mucho mejor, sobre todo porque tiene SRAM como el ZX-Uno y el microcontrolador te permitiría cargar los cores desde la SD muy fácilmente (como hace la Myst). Pero no existía cuando compre la Pro así me tengo que aguantar con lo que hay.antoniovillena escribió:Por otro lado hay versiones más modernas de estas placas, en concreto la Papilio DUO-512Kb
http://www.seeedstudio.com/depot/Papili ... cPath=6_10
Con su placa de periféricos
http://www.seeedstudio.com/depot/Classi ... cPath=6_10
- antoniovillena
- Demonio segundo orden
- Mensajes: 1596
- Registrado: 02 Abr 2013, 19:06
- Been thanked: 1 time
Re: ZXPP, clon de Spectrum en una Papilio Pro
Sí, lo de la SDRAM es un problema. El prototipo 0 del ZX-Uno fue una placa MOD-VGA. Dicha placa venía montada de serie con una SDRAM. Por suerte vendían una versión barata sin SDRAM y por la parte de atrás había una huella para SRAM, por lo que comprando esta y un chip de SRAM se podía hacer el apaño.
Si es por aprender, con la BRAM tienes lo justo para un 48K. El conector DB9 va casi directo a un pin de la FPGA, así que ten mucho cuidado con las tensiones que le metes. Lo ideal es hacerte un circuito de EAR basado en un transistor como tiene el ZX-Uno (mírate los esquemáticos).
Si es por aprender, con la BRAM tienes lo justo para un 48K. El conector DB9 va casi directo a un pin de la FPGA, así que ten mucho cuidado con las tensiones que le metes. Lo ideal es hacerte un circuito de EAR basado en un transistor como tiene el ZX-Uno (mírate los esquemáticos).
- Kyp
- Hermano de Lucifer
- Mensajes: 3391
- Registrado: 30 Sep 2013, 14:54
- Ubicación: Madrid
- Has thanked: 29 times
- Been thanked: 157 times
Re: ZXPP, clon de Spectrum en una Papilio Pro
Lo se, lo se. Sigo vuestros progresos desde le principioantoniovillena escribió:Sí, lo de la SDRAM es un problema. El prototipo 0 del ZX-Uno fue una placa MOD-VGA. Dicha placa venía montada de serie con una SDRAM. Por suerte vendían una versión barata sin SDRAM y por la parte de atrás había una huella para SRAM, por lo que comprando esta y un chip de SRAM se podía hacer el apaño.
Estoy viendo la posibilidad de adaptar un controlador que hay para la SDRAM de forma que simule el uso de una SRAM. Como la SDRAM trabaja a una frecuencia mucho más rápida de lo que necesito (100 MHZ o más), se podría meter un módulo intermedio que exponga los pines de una SRAM, e internamente envié los comandos y almacene los datos que haga falta para manejar la SDRAM. Además eso me hace falta para poder clonar el DivMMC porque con la BRAM ya no tengo la ROM/RAM necesaria.
Si, también me he 'inspirado' en el diseño del ZX-Uno para estoantoniovillena escribió:Si es por aprender, con la BRAM tienes lo justo para un 48K. El conector DB9 va casi directo a un pin de la FPGA, así que ten mucho cuidado con las tensiones que le metes. Lo ideal es hacerte un circuito de EAR basado en un transistor como tiene el ZX-Uno (mírate los esquemáticos).
- Kyp
- Hermano de Lucifer
- Mensajes: 3391
- Registrado: 30 Sep 2013, 14:54
- Ubicación: Madrid
- Has thanked: 29 times
- Been thanked: 157 times
Re: ZXPP, clon de Spectrum en una Papilio Pro
Paso 01, vídeo VGA
Este paso no es que sea estrictamente necesario, pero es lo primero que se suele hacer con una FPGA ya que es algo relativamente sencillo y, la verdad, es bastante estimulante ver que el dinero que te has gastado en la tarjeta hace algo más que encender y apagar unos cuantos LEDs.
Si buscáis en internet como debe ser una señal VGA verás un montón de información sobre diagramas de tiempos... duración de señales y sincronismos... y un montón de números para calcular cuanto debe durar cada señal.
En realidad es mucho más sencillo.
Una señal VGA estándar de 640x480 a 60Hz tiene la forma siguiente:
- Cada línea horizontal tiene 800 píxels. 640 son visibles y durante el resto se genera el sincronismo horizontal: |------640------|-HS-|
- Cada línea vertical tiene 525 píxels. 480 son visibles y durante el resto se genera el sincronismo vertical: |------480------|-VS-|
Los sincronismos no se generan durante todo el tiempo no visible, hay unos espacios antes y después llamados front y back porch que supongo eran necesarios para las TVs analógicas.
En esta página tenéis los parámetros para casi cualquier resolución VGA:
http://tinyvga.com/vga-timing
Necesitamos dos contadores, el horizontal cuenta de 0 a 799 y cada vez que pasamos por el 799 incrementamos el vertical que cuenta de 0 a 524.
Para generar los sincronismo simplemente mantenemos a 1 lógico la señal (es activa a nivel bajo) mientras no esté dentro de los rangos especificados, y la ponemos a 0 cuando corresponda. En este caso, del 656 al 751 para el horizontal y del 490 al 491 para el vertical.
Finalmente, mientras estemos en la zona visible ponemos un color (blanco) y a negro el resto del tiempo:
Jugando con el valor asignado a la señal "rgb" durante el área visible se pueden hacer unos bonitos degradados.
Este paso no es que sea estrictamente necesario, pero es lo primero que se suele hacer con una FPGA ya que es algo relativamente sencillo y, la verdad, es bastante estimulante ver que el dinero que te has gastado en la tarjeta hace algo más que encender y apagar unos cuantos LEDs.
Si buscáis en internet como debe ser una señal VGA verás un montón de información sobre diagramas de tiempos... duración de señales y sincronismos... y un montón de números para calcular cuanto debe durar cada señal.
En realidad es mucho más sencillo.
Una señal VGA estándar de 640x480 a 60Hz tiene la forma siguiente:
- Cada línea horizontal tiene 800 píxels. 640 son visibles y durante el resto se genera el sincronismo horizontal: |------640------|-HS-|
- Cada línea vertical tiene 525 píxels. 480 son visibles y durante el resto se genera el sincronismo vertical: |------480------|-VS-|
Los sincronismos no se generan durante todo el tiempo no visible, hay unos espacios antes y después llamados front y back porch que supongo eran necesarios para las TVs analógicas.
En esta página tenéis los parámetros para casi cualquier resolución VGA:
http://tinyvga.com/vga-timing
Necesitamos dos contadores, el horizontal cuenta de 0 a 799 y cada vez que pasamos por el 799 incrementamos el vertical que cuenta de 0 a 524.
Para generar los sincronismo simplemente mantenemos a 1 lógico la señal (es activa a nivel bajo) mientras no esté dentro de los rangos especificados, y la ponemos a 0 cuando corresponda. En este caso, del 656 al 751 para el horizontal y del 490 al 491 para el vertical.
Finalmente, mientras estemos en la zona visible ponemos un color (blanco) y a negro el resto del tiempo:
Código: Seleccionar todo
process(clock25)
begin
if rising_edge(clock25) then
if x < 799 then x <= x+1;
else
x <= (others => '0');
if y < 524 then y <= y+1;
else
y <= (others => '0');
end if;
end if;
if x >= 640+16 and x < 640+16+96 then hs <= '0'; else hs <= '1'; end if;
if y >= 480+10 and y < 480+10+ 2 then vs <= '0'; else vs <= '1'; end if;
if x < 640 and y < 480 then
rgb <= x"777";
else
rgb <= x"000";
end if;
end if;
end process;
No tiene los permisos requeridos para ver los archivos adjuntos a este mensaje.
- Kyp
- Hermano de Lucifer
- Mensajes: 3391
- Registrado: 30 Sep 2013, 14:54
- Ubicación: Madrid
- Has thanked: 29 times
- Been thanked: 157 times
Re: ZXPP, clon de Spectrum en una Papilio Pro
Paso 02, decodificando la pantalla
Ahora que ya sabemos como generar la señal de vídeo, para generar una imagen solamente necesitamos saber que información de color enviar por la salida RGB para cada píxel.
Como tenemos una pantalla de 640x480 píxels y el Spectrum tiene una resolución de 256x192 píxels voy a hacer lo siguiente para llenar la pantalla. Voy a aplicar un zoom de x2 a la imagen quedando en 512x384 píxels. El resto lo mostramos como borde lo que nos da 640-512=128, es decir, 64 píxels a derecha e izquierda y 480-384=96, es decir, 48 píxels por encima y por debajo. Hacer el zoom x2 es muy sencillo, simplemente hay que dividir entre 2 el contador horizontal y el vertical a la hora de calcular las posiciones de memoria que contienen la información para cada píxel.
La información de cada píxels está en dos posiciones de memoria, una indica si se ve el color de tinta o de papel y la otra los atributos (tinta, papel, brillo y flash). Como sólo podemos leer una posición de memoria cada vez, vamos a usar dos registros para guardar estos datos. Esto hay que hacerlo para cada 8 píxels (un byte).
Además, necesitamos obtener la información antes de que se vaya a pintar cada bloque de 8 píxelsy hay que conservarla mientras se pintan y a la vez leemos la información de los 8 siguientes. Por lo que necesitamos otros dos registros más.
Aquí lo complicado es tener el dato en el momento justo. En una FPGA las transferencias de datos son síncronas, esto es, todo pasa en los flancos de la señal de reloj. Por ejemplo, en un flaco positivo del reloj asignas la dirección a leer y al siguiente flanco obtienes el dato. Igualmente, los registros que guardan la información hacen la transferencia en un flanco de reloj.
Por último, como mientras se pinta un bloque de 8 píxels hay que cargar los datos de color de los 8 siguientes, uso un contador adelantado 16 pulsos de reloj (8x2 del zoom) que solo cuenta las coordenadas de pantalla, 0 a 511 (resolución horizontal) y 0 a 383 (resolución vertical). De esta forma, cuando voy a pintar por ejemplo el píxel (23,5) que contador vale (7, 5), o en el caso especial de los primeros 8 píxels (3, 0) valdría (499, 383).
El procedimiento queda de la siguiente forma, para cada 16 incrementos del contador horizontal hacemos lo siguiente (cuento de 0 a 15):
- 0: asignamos al bus de direcciones la dirección de memoria que contiene que 8 píxels están encendidos o apagados del próximo byte.
- 1: la memoria devuelve el dato.
- 2: traspasamos el dato al registro que guarda la información sobre los siguientes 8 píxels.
- 8: asignamos al bus de direcciones la dirección de memoria que contiene los atributos.
- 9: la memoria devuelve el dato.
-10: traspasamos el dato al registro que guarda la información sobre los atributos de los siguientes 8 píxels.
-15: traspasamos los datos de los dos registros a los otros dos que mantendrán la información de color de los 8 píxels que se van a pintar mientras se lee la de los 8 siguientes.
- En el resto de 'slots' no hacemos nada.
Una vez que tenemos la información de bitmap y atributos ya es cuestión de ver si el píxel que se va a pintar está encendido o apagado y en función de eso, si tiene o no flash o brillo, escoger un color de la paleta.
Ahora que ya sabemos como generar la señal de vídeo, para generar una imagen solamente necesitamos saber que información de color enviar por la salida RGB para cada píxel.
Como tenemos una pantalla de 640x480 píxels y el Spectrum tiene una resolución de 256x192 píxels voy a hacer lo siguiente para llenar la pantalla. Voy a aplicar un zoom de x2 a la imagen quedando en 512x384 píxels. El resto lo mostramos como borde lo que nos da 640-512=128, es decir, 64 píxels a derecha e izquierda y 480-384=96, es decir, 48 píxels por encima y por debajo. Hacer el zoom x2 es muy sencillo, simplemente hay que dividir entre 2 el contador horizontal y el vertical a la hora de calcular las posiciones de memoria que contienen la información para cada píxel.
La información de cada píxels está en dos posiciones de memoria, una indica si se ve el color de tinta o de papel y la otra los atributos (tinta, papel, brillo y flash). Como sólo podemos leer una posición de memoria cada vez, vamos a usar dos registros para guardar estos datos. Esto hay que hacerlo para cada 8 píxels (un byte).
Además, necesitamos obtener la información antes de que se vaya a pintar cada bloque de 8 píxelsy hay que conservarla mientras se pintan y a la vez leemos la información de los 8 siguientes. Por lo que necesitamos otros dos registros más.
Aquí lo complicado es tener el dato en el momento justo. En una FPGA las transferencias de datos son síncronas, esto es, todo pasa en los flancos de la señal de reloj. Por ejemplo, en un flaco positivo del reloj asignas la dirección a leer y al siguiente flanco obtienes el dato. Igualmente, los registros que guardan la información hacen la transferencia en un flanco de reloj.
Por último, como mientras se pinta un bloque de 8 píxels hay que cargar los datos de color de los 8 siguientes, uso un contador adelantado 16 pulsos de reloj (8x2 del zoom) que solo cuenta las coordenadas de pantalla, 0 a 511 (resolución horizontal) y 0 a 383 (resolución vertical). De esta forma, cuando voy a pintar por ejemplo el píxel (23,5) que contador vale (7, 5), o en el caso especial de los primeros 8 píxels (3, 0) valdría (499, 383).
El procedimiento queda de la siguiente forma, para cada 16 incrementos del contador horizontal hacemos lo siguiente (cuento de 0 a 15):
- 0: asignamos al bus de direcciones la dirección de memoria que contiene que 8 píxels están encendidos o apagados del próximo byte.
- 1: la memoria devuelve el dato.
- 2: traspasamos el dato al registro que guarda la información sobre los siguientes 8 píxels.
- 8: asignamos al bus de direcciones la dirección de memoria que contiene los atributos.
- 9: la memoria devuelve el dato.
-10: traspasamos el dato al registro que guarda la información sobre los atributos de los siguientes 8 píxels.
-15: traspasamos los datos de los dos registros a los otros dos que mantendrán la información de color de los 8 píxels que se van a pintar mientras se lee la de los 8 siguientes.
- En el resto de 'slots' no hacemos nada.
Una vez que tenemos la información de bitmap y atributos ya es cuestión de ver si el píxel que se va a pintar está encendido o apagado y en función de eso, si tiene o no flash o brillo, escoger un color de la paleta.
Código: Seleccionar todo
process(clock25)
variable bpre : std_logic_vector(7 downto 0); -- precarga del bitmap
variable apre : std_logic_vector(7 downto 0); -- precarga de atributos
variable i, p : std_logic_vector(2 downto 0); -- i = INK, p = PAPER
variable b, c : integer; -- b = nº de píxel (de los 8 de cada byte) que se va a pintar
-- c = color resultante a pintar después de tener en cuenta si es INK o PAPER, el brillo y el flash
begin
if rising_edge(clock25) then
-- contadores de la señal VGA
if x < 799 then x <= x+1;
else
x <= (others => '0');
if y < 524 then y <= y+1;
else
y <= (others => '0');
f <= f+1; -- contador de flash
end if;
end if;
-- señales de sincronismo
if x >= 640+16 and x < 640+16+96 then hs <= '0'; else hs <= '1'; end if;
if y >= 480+10 and y < 480+10+ 2 then vs <= '0'; else vs <= '1'; end if;
-- zona visible
if x >= 64 and x < 64+512 and y >= 48 and y < 48+384 then
-- contador de coordenadas de pantalla adelantado 16 pulsos
if x = 64+512-16 and y = 48+383 then xy <= (others => '0'); else xy <= xy+1; end if;
-- proceso de captura de datos desde la memoria
if xy(3 downto 0) = "0000" then va <= xy(17 downto 16)&xy(12 downto 10)&xy(15 downto 13)&xy(8 downto 4); end if;
if xy(3 downto 0) = "1000" then va <= "110"&xy(17 downto 13)&xy( 8 downto 4); end if;
if xy(3 downto 0) = "0010" then bpre := vd; end if;
if xy(3 downto 0) = "1010" then apre := vd; end if;
if xy(3 downto 0) = "1110" then bmap <= bpre; attr <= apre; end if;
-- calculamos en indice dentro de la paleta de colores
-- valores de INK y PAPER
b := 7-to_integer(unsigned(x(3 downto 1)));
i := attr(2 downto 0);
p := attr(5 downto 3);
-- color del píxel en función de si está encendido o apagado y el flash
if attr(7) = '1' then
if f(5) = '1' then
if bmap(b) = '0' then c := to_integer(unsigned(i)); else c := to_integer(unsigned(p)); end if;
else
if bmap(b) = '0' then c := to_integer(unsigned(p)); else c := to_integer(unsigned(i)); end if;
end if;
else
if bmap(b) = '1' then c := to_integer(unsigned(i)); else c := to_integer(unsigned(p)); end if;
end if;
-- atributo de brillo
if attr(6) = '1' then c := c+8; end if;
-- color definitivo
rgb <= palette(c);
elsif x < 640 and y < 480 then
-- zona del borde
rgb <= x"700";
else
-- zona no visible
rgb <= x"000";
end if;
end if;
end process;
No tiene los permisos requeridos para ver los archivos adjuntos a este mensaje.