Memoria utilizable

Programando el Amstrad en Ensamblador.
Reglas del Foro
Debido a que hay varios temas pidiendo ayuda para programar en ensamblador máquinas distintas al Amstrad CPC, con micro distinto al Z80 y que incluso dependen del sistema operativo, nos vemos en la necesidad de poner por escrito que estos posts son bienvenidos pero que no es el lugar adecuado ya que por estos lares nos dedicamos más al ensamblador del Z80, un microprocesador de 8 bits que tuvo su gran auge en ordenadores y consolas de los años 80.

De todas formas, esto no quita que alguien que sepa del asunto pueda postear alguna respuesta pero es más fácil encontrar foros dedicados a programar en ensamblador en Windows o MS-DOS que ayudarán más que nosotros:
http://www.lawebdelprogramador.com/news ... nsamblador
Avatar de Usuario
Artaburu
Trasteador
Trasteador
Mensajes: 8419
Registrado: Vie 07 Oct , 2005 6:18 pm
Ubicación: En tu pantalla

Re: Memoria utilizable

Mensajepor Artaburu » Jue 29 Nov , 2012 11:43 pm

Ostras, pues se mueve la mar de bien =D> =D>
Salu2,
Arta

Avatar de Usuario
6128
Moderador
Moderador
Mensajes: 7910
Registrado: Lun 12 Dic , 2005 6:08 pm

Re: Memoria utilizable

Mensajepor 6128 » Vie 30 Nov , 2012 9:59 am

Tranquilo que al ser una prueba gráfica nadie se va a quejar de los gráficos.
Al contrario. Yo creo que están bien. Sin pulir, pero bien.

Lo importante es ver que se mueven de forma decente. =D>

gg
I am The Forum
I am The Forum
Mensajes: 2290
Registrado: Mié 13 Dic , 2006 10:48 am

Re: Memoria utilizable

Mensajepor gg » Vie 30 Nov , 2012 5:10 pm

Tiene una pinta estupenda. Ánimo y adelante con el proyecto.
Saludos,
gg.

pacomix
Forum Addict
Forum Addict
Mensajes: 460
Registrado: Dom 11 Nov , 2012 8:05 pm

Re: Memoria utilizable

Mensajepor pacomix » Vie 30 Nov , 2012 9:20 pm

"DaDMaN"]Consejo... Ya que te has metido de cabeza en un juego y en usar 64K nada más, para ahorrar memoria, redimensiona las pantallas a 256x192 (128x192 en Mode 0). Es el equivalente a Spectrum. De ese modo, las pantallas en lugar de ocupar 16K, ocuparán 12K cada una, sumando un total de 24K entre principal y buffer. Importante señalar que la memoria no es lineal. En este caso, tendrás bloques de 512bytes libres (un total de 8 ) lineales intercalados en las pantallas que podrás usar para meter pequeños gráficos, rutinas, tablas, paleta de colores, etc... El hardware del CPC te permite "redimensionar" la pantalla, moverla de sitio, desplazarla, etc...

Tras cambiar la resolución, tendrás que adaptar las rutinas de Sprites para la nueva condición.
Mmmmmh... aquí no entiendo una cosa. Si uso 256 píxeles de ancho estaría usando 128 bytes para el ancho con lo cual el gasto sería mayor que usando el modo 160x200 (80bytes) por cada línea, ¿no? O me estoy aquí perdiendo un punto bastante importante... ¿Podrías explicarlo mejor o indicar alguna web donde pueda entender eso mejor? :) La verdad que si es así eso supondría un ahorro de memoria bastante considerable. 4KB x dos buffers de pantalla = 8KB O_o
Otro punto importante sobre el doble buffer, es que no lo hagas al estilo "spectrum", con LDIs volcando de una pantalla a otra. En el CPC tenemos un maravilloso hardware que nos permite conmutar "instantáneamente" el puntero de memoria gráfico a "cualquier" dirección de RAM. Puedes decirle al CPC que te coloque la VRAM en &C000 (como está al arrancar) o bien en &8000, o en &4000, o donde se te antoje y la conmutación es inmediata. Por lo tanto, en CPC, lo suyo es dibujar en &8000 mientras muestras la pantalla en &c000 y al terminar, cambiazo del puntero y mostrar la pantalla en &8000 (mientras actualizas a escondidas &C000) y así consecutivamente. No tendrás parpadeos y además es MUY rápido (pues no andas volcando con LDIs a cascoporro)...
Exacto. Así es como lo hice en un principio. Pero al principio lo que hacía era paginar y cambiar la Screen Address (estaba programando para un 128KB) y siempre escribía en la 0x4000 con lo que me ahorraba en cambiar un poco la lógica de las rutinas de pintado y duplicar las mismas.
Actualmente lo tengo implementado de la forma que has descrito.
Con todo esto liberarás RAM y aumentarás la velocidad de pintado exponencialmente (nosotros lo hicimos así en el juego Teodoro y hemos tenido que "pausarlo" porque iba demasiado rápido).
Actualmente el problema que tengo con el rendimiento es por las rutinas que usan transparencias en las cuales se hace un proceso adicional por cada byte a transferir con lo cual se gasta bastante más tiempo en ellas. Esa las uso prácticamente para todos los sprites en pantalla. Si pinto con las mismas rutinas que uso para repintar los tiles de fondo la cosa mejora bastante para los 9 sprites que se pintan por cada paso al mismo tiempo en pantalla. Aunque aún no tengo implementada la lógica y lo que hay en youtube sería un caso "extremo" ya que todo se está pintando en cada paso. En el juego original los sprites se mueven, se paran por un segundo o así (pensando) luego se vuelven a mover, etc... Con lo que la cosa debería mejorar cuando implemente la lógica de los enemigos.
¡Por cierto tu Teodoro sí que tiene buena pinta y no lo que he subido jaja!
Lo último, para conseguir más RAM, es que tengas los datos comprimidos con algún compresor como APLIB, EXOMIZER y sucedáneos varios y descomprimirlos sólo cuando los necesites...

Así podrás meter bastante historia en 64K sin morir en el intento. Si tienes alguna duda, ya sabes, aunque no soy programador, los conceptos y la teoría los tengo bastante claros.
¡Gracias por los tips! Sí, de hecho el tema de las rutinas compresoras es algo que tenía presente, pero de momento aún no he llegado a esa parte. Aún sigo haciendo pruebas de rendimiento a ver qué sería factible para poder desarrollar un juego equilibrado, jugabilidad/aspecto gráfico/features. :)

P.D.: La próxima vez, mejor un juego para 128K :mrgreen:
Jaja sí... hoy en día no creo que merezca la pena mucho el esfuerzo en meterlo todo en 64Kb teniendo los emuladores. Pero es más un reto personal que otra cosa.

¡Saludetes!

Avatar de Usuario
DaDMaN
Keeper of The Forum
Keeper of The Forum
Mensajes: 796
Registrado: Jue 16 Mar , 2006 10:51 pm

Re: Memoria utilizable

Mensajepor DaDMaN » Vie 30 Nov , 2012 10:50 pm

Te explico lo de la resolución...

Concretamente te he puesto este dato: 256x192 (128x192 en Mode 0)

Como sabes, el CPC tiene 3 modos de "pantalla" o de píxel, a saber:
  • 1. Modo 0 - 192x272 píxeles - 16 colores simultáneos de una paleta de 27 (2 píxeles por byte)
    2. Modo 1 - 384x272 píxeles - 4 colores simultáneos de una paleta de 27 (4 píxeles por byte)
    3. Modo 2 - 768x272 píxeles - 2 colores simultáneos de una paleta de 27 (8 píxeles por byte)
Estos son los valores "absolutos" de la máquina que corresponden al límite visible del monitor del CPC (o de un televisor). El hardware del CPC permite modificar esas resoluciones cómo se te antoje, tomando como referencia 1 chr (8 píxeles) en cuanto al tamaño horizontal. En vertical, se puede definir "línea a línea", pero eso ahora mismo no es lo importante.

Como te decía, el hardware del CPC permite modificar esos valores (incluso nos permite hacer la pantalla más grande que el monitor y dibujar "fuera" de él, para hacer scroll por hardware y no ver lo que vas pintando). Por supuesto, a mayor tamaño, más memoria se necesita y ahí es donde el CPC tiene la gran limitación, pues toda esa VRAM se descuenta de la memoria principal (el primer banco de 64K).

De ese modo, el fabricante, decidió emplear resoluciones menores predefinidas en el firmware del equipo para que no sobrepasasen los 16K y únicamente se usase una página de la RAM principal quedando reducidas a:
  • 1. Modo 0 - 160x200 píxeles (32.000 en total). Dividido entre 2 (2 píxeles por byte) nos quedan 16.000 bytes
    2. Modo 1 - 320x200 píxeles - (64.000 en total). Dividido entre 4 (4 píxeles por byte) nos quedan 16.000 bytes
    3. Modo 2 - 640x200 píxeles - (128.000 en total). Dividido entre 8 (8 píxeles por byte) nos quedan 16.000 bytes
Con estas resoluciones, ves que siempre se emplean 16K (no llega) de RAM por pantalla. Como la página de RAM es de 16.384 bytes y se están usando 16.000, nos sobran 384 bytes de RAM que NO SON LINEALES. Supongo que a estas alturas ya habrás descubierto que la pantalla está dividida en 8 bloques (a groso modo). En las resoluciones estándar, para saltar de un bloque a otro hay que sumarle 2048 bytes al offset, de los cuales, 2000 son visibles en pantalla y 48 son "invisibles". Esto corresponde a los 384 bytes que nos sobran que si los divides entre 8 bloques, tenemos que disponemos de 48 bytes libres LINEALES por bloque de pantalla.

Hay un modo de pantalla "ideal" que se puede definir de 16.384 bytes exactos (sin zonas ocultas) y que tal vez facilitaría los saltos (los cambios de offset) en las rutinas de sprites (me refiero a la ordenación de líneas):
  • 1. Modo 0 - 128x256 píxeles (32.768 en total). Dividido entre 2 (2 píxeles por byte) nos quedan 16.384 bytes
    2. Modo 1 - 256x256 píxeles - (65.536 en total). Dividido entre 4 (4 píxeles por byte) nos quedan 16.384 bytes
    3. Modo 2 - 512x256 píxeles - (131.072 en total). Dividido entre 8 (8 píxeles por byte) nos quedan 16.384 bytes
Esto resultaría en un "cuadrado perfecto" en la pantalla.

Pero sobre el caso concreto que te he comentado (256x192, equivalente a la resolución de Spectrum) los resultados son los siguientes:
  • 1. Modo 0 - 128x192 píxeles (24.576 en total)/2 = 12.288 bytes
    2. Modo 1 - 256x256 píxeles - (49.152 en total)/4 = 12.288 bytes
    3. Modo 2 - 512x256 píxeles - (98.304 en total)/8 = 12.288 bytes
Como la página de RAM es de 16Kbytes (16.384 bytes), nos quedan 4.096 bytes que NO SON LINEALES y LIBRES. Ya hemos dicho que la pantalla está dividida en 8 bloques, por lo tanto: 4.096 bytes / 8 = 512 bytes LINEALES libres por bloque de pantalla.

No sé si te ha quedado claro o no, jejejejejejeje.

Para cambiar los valores del CRTC (afectando al tamaño de pantalla y al centrado), hay que usar 2 puertos:
  • - &BC00: Selección de registro
    - &BD00: Valor del registro seleccionado
Y para no complicarnos, te dejo los valores de los registros para dejar la pantalla en modo "spectrum":
  • - R1 = 32 (32 caracteres de ancho)
    - R2 = 42 (Posición horizontal)
    - R6 = 24 (24 caracteres de alto)
    - R7 = 30 (Posición vertical)
    - R9 = 7 (8 píxeles de altura por carácter)
En Ensamblador vendría a ser algo tan sencillo como esto:

Código: Seleccionar todo

; Ancho de pantalla en caracteres (32)
ld bc,&bc01
out (c),c
ld bc,&bd00+32
out (c),c

; Posición horizontal de la pantalla
ld bc,&bc02
out (c),c
ld bc,&bd00+42
out (c),c

; Altura de la pantalla en caracteres (24)
ld bc,&bc06
out (c),c
ld bc,&bd00+24
out (c),c

; Posición vertical de la pantalla
ld bc,&bc07
out (c),c
ld bc,&bd00+30
out (c),c

; Cada carácter del CRTC tendrá 8 píxeles de altura
ld bc,&bc09
out (c),c
ld bc,&bd00+7
out (c),c
Y en BASIC mondo y lirondo el programa queda tal que así:

Código: Seleccionar todo

1 BORDER 0: ' Borde color negro
10 OUT &BC00,1:OUT &BD00,32: ' R1 = 32
20 OUT &BC00,2:OUT &BD00,42: ' R2 = 42
30 OUT &BC00,6:OUT &BD00,24: ' R6 = 24
40 OUT &BC00,7:OUT &BD00,30: ' R7 = 30
50 OUT &BC00,9:OUT &BD00,7: ' R9 = 7
Y la pantalla resultante sería algo así:

Imagen

El tamaño de la pantalla es INDEPENDIENTE al MODO de PANTALLA (o tamaño del píxel en relación al máximo de los colores mostrados simultáneamente).

Bueno, no sé si me he explicado bien. Lo he hecho todo un poco rápido, pero creo que queda más o menos claro.

Saludos.

pacomix
Forum Addict
Forum Addict
Mensajes: 460
Registrado: Dom 11 Nov , 2012 8:05 pm

Re: Memoria utilizable

Mensajepor pacomix » Sab 01 Dic , 2012 5:52 pm

¡Muchas gracias por tan detallada información!
Voy a ver ahora si hago algunas pruebas y reprogramo las rutinas... Lo malo que voy a tener que redimensionar todo todo todo lo que he hecho hasta el momento. Mirándolo del lado bueno se reduce el tamaño de pantalla pero también se reduce la cantidad de cosas a pintar así que bueno. Supongo que después de adaptarlo todo debería ir todo también más rápido.

¡Saludos!

pacomix
Forum Addict
Forum Addict
Mensajes: 460
Registrado: Dom 11 Nov , 2012 8:05 pm

Re: Memoria utilizable

Mensajepor pacomix » Mar 25 Dic , 2012 10:54 pm

Bueno después de un tiempo sin tocar nada vuelvo de nuevo a la carga ya que pude meterle mano a esto durante los dos últimos días... Sí... ¿increíble verdad?
Pues pongo una pequeña actualización con el cambio que Dadman sugirió. Implementé las rutinas y modifiqué el código de forma que pudiera contrastar entre el modo 160x200 y el 128x192. Después de medir el tiempo se consigue un incremento de 2 frames por segundo para 8 sprites en pantalla simultáneos + repintado correspondiente del fondo.

Por cada frame se pintan 8 sprites + 4-6 tiles por cada sprite.

En modo 160x200 tenemos:
Sprites: 12x24 pixels
Tiles: 5x16 pixels
Tiempo de pintado: 100-106ms (10FPS aprox.)
0004.bmp
CPC Bros - 160x200
(433.05 KiB) No descargado aún


En modo 128x192 tenemos:
Sprites: 10x24
Tiles: 4x16
Tiempo de pintado: 80-86ms (12FPS aprox.)
0004.bmp
CPC Bros - 160x200
(433.05 KiB) No descargado aún
No es mucho pero habría que desplazar la pantalla hacia abajo un poco ya que se quedaría algo corta en la parte superior y meter con calzador los puntos, marcador de vidas y el SNOW de la vida extra. Así que no sabría que hacer exactamente... Lo dejo a voto popular.

Pros 160x200:
- Pantalla un poco más alta. Se podría meter el marcador en los 8 pixels de la parte superior.
- Gráficos un poco más detallados. Mmmmh... 2 pixels más de ancho.
- Pantalla relativamente más grande.
Contras 160x200:
- Los buffers de pantalla ocupan 32Kb.
- Pintado un poco más lento.

Pros 128x192:
- Pintado ligeramente más rápido.
- Tenemos disponibles 8KB en 16 bloques de 512bytes each.

Contras 128x192:
- Pantalla algo más baja. Tal vez se deberían redimensionar también la altura de los sprites y tiles para meter el marcador.
- Aprovechar las áreas de memoria libres requiere algo de trabajo en el código.

Personalmente me gustaría hacer que el juego cupiese en 64kb pero visto lo visto creo que la tarea se presenta bastante difícil así que seguramente tendré que hacer una versión multicarga.

¿Qué opináis?

P.S.: Mmmmh... ¿no se debería mover el hilo a otro foro? :D
Adjuntos
0005.bmp
CPC Bros - 128x192
(433.05 KiB) No descargado aún


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro


La Comunidad Española
ESP Soft, juegos para tu CPC Foro de Amstrad CPC Todos los juegos para CPC en un CD Web dedicada al Amstrad CPC (utilidades) Información útil para el CPC (talleres) Selección de juegos de Amstrad CPC Mundo CPC Pree Play then any Key CPC Basic