Página 1 de 2

Sprites en el modo radastaniano del ZX Uno

Publicado: Dom, 18 Ene 2015, 00:34
por radastan
Veamos, estoy en ese punto en el que uno no sabe si se ha vuelto majareta. Al adaptar mi rutina de Sprites al ZX Uno consigo imprimir sólo las primeras líneas pero no las siguientes de cada sprite. En concreto falla cuando tengo que incrementar el registro D para que apunte al siguiente cuarteto de líneas (van de 4 en 4 en el registro E, ya que cada línea tiene 64 bytes o 128 pixels).

Os dejo la rutina por si alguien encuentra el fallo:

$this->bbcode_second_pass_code('', '
// ___________________________________________
// Posiciona un Sprite de 8x8 a color
// ___________________________________________

void put_sprite_x8 (unsigned char *posicion, unsigned int x, unsigned int y)
{
// -------------------------------------------
// RUTINA DE IMPRESION DE UN SPRITE 8x8 PIXELS
// EN CUALQUIER POSICION DE BYTES (cada byte dos pixels horizontales)
// ENTRADAS:
// D será la posición del cursor vertical en pixels
// E será la posición del cursor horizontal en parejas de pixels
// HL es la posición de memoria donde tenemos el sprite
// SALIDAS: se escribe en el mapa de pantalla
// ADVERTENCIAS: no comprueba límites de pantalla
// -------------------------------------------
#asm
ld hl,2 ; Pasamos la variable de entrada al acumulador
add hl,sp
ld d, (hl) ; D es el valor Y
inc hl
inc hl
ld e, (hl) ; E es el valor X
inc hl
inc hl
ld a, (hl)
inc hl
ld h, (hl)
ld l, a ; HL es el puntero al sprite

ld a, d ; recuperamos el valor vertical
rrca
rrca ; rotamos para dejar su valor en múltiplos de 64 (linea, de dos en dos pixels)
and 192 ; borramos el resto de bits por si las moscas
or e ; sumamos el valor horizontal
ld e, a ; e preparado
ld a, d ; cargamos el valor vertical
rrca
rrca ; rotamos para quedarnos con los bits altos
and 63 ; borramos el resto de bits
or 64 ; nos posicionamos a partir de 16384 (16384=64+0 en dos bytes)
ld d, a ; d preparado, ya tenemos la posición en pantalla

ld b,0
ld c,8 ; Indicamos que vamos a pintar 8 líneas
.draw ; dibujamos 8 pixels (4 bytes)
push de ; guardamos DE (la posición de pantalla)
push bc ; Guardamos las iteraciones (8 líneas)
ldi
ldi
ldi
ldi
pop bc ; recuperamos el número de iteraciones
pop de ; recuperamos DE
ld a,e
add a,64 ; incrementamos una línea
ld e,a
jr nc, sigue
inc d ; incrementamos D si sale acarrero al incrementar E en 64 bytes
.sigue
dec c ; decrementamos ********* AQUI DEBE ESTAR EL PROBLEMA **********
jr nc, draw

ret

#endasm
}
')

Mañana le daré otro tiento, a ver que puñetas pasa.

Re: Sprites en el modo radastaniano del ZX Uno

Publicado: Dom, 18 Ene 2015, 00:50
por antoniovillena
El problema está en el salto condicional después del "dec c". Debe ser jr nz en lugar de jr nc.

Re: Sprites en el modo radastaniano del ZX Uno

Publicado: Dom, 18 Ene 2015, 00:56
por antoniovillena
Los push y pop dentro del bucle hacen que vaya muy lento. Prueba a poner algo así, verás cómo se acelera.

$this->bbcode_second_pass_code('', '
ld b, 8 ; Indicamos que vamos a pintar 8 líneas
.draw ; dibujamos 8 pixels (4 bytes)
ld c, 4 ; Indicamos que vamos a pintar 8 píxeles
ldi
ldi
ldi
ldi
ld a, e
add a, 60 ; incrementamos una línea
ld e, a
jr nc, sigue
inc d ; incrementamos D si sale acarrero al incrementar E en 60 bytes
.sigue
djnz draw
')

Re: Sprites en el modo radastaniano del ZX Uno

Publicado: Dom, 18 Ene 2015, 01:38
por radastan
Esto me pasa por programar a deshoras... Gracias!

:ymca:

Re: Sprites en el modo radastaniano del ZX Uno

Publicado: Lun, 19 Ene 2015, 17:26
por Metalbrain
$this->bbcode_second_pass_quote('antoniovillena', '
')$this->bbcode_second_pass_code('', '
ld b, 8 ; Indicamos que vamos a pintar 8 líneas
.draw ; dibujamos 8 pixels (4 bytes)
ld c, 4 ; Indicamos que vamos a pintar 8 píxeles
ldi
ldi
ldi
ldi
ld a, e
add a, 60 ; incrementamos una línea
ld e, a
jr nc, sigue
inc d ; incrementamos D si sale acarrero al incrementar E en 60 bytes
.sigue
djnz draw
')


Hmmm... no he podido resistirme:

$this->bbcode_second_pass_code('', '
ld b, 8 ; Indicamos que vamos a pintar 8 líneas
.draw ; dibujamos 8 pixels (4 bytes)
ld c, 64 ; Indicamos que vamos a pintar 8 píxeles
ldi
ldi
ldi
ldi
ld a, e
add a, c ; incrementamos una línea
ld e, a
jr nc, sigue
inc d ; incrementamos D si sale acarrero al incrementar E en 60 bytes
.sigue
djnz draw
')

Re: Sprites en el modo radastaniano del ZX Uno

Publicado: Lun, 19 Ene 2015, 17:43
por antoniovillena
Bien visto. Yo pensé en otra optimización pero no la puse para no liar a radastan. La pongo junto con otra que se me ha ocurrido ahora (y la tuya).

$this->bbcode_second_pass_code('', '
ld b, 8 ; Indicamos que vamos a pintar 8 líneas
ld a, e
.draw ; dibujamos 8 pixels (4 bytes)
ld c, 64 ; Indicamos que vamos a pintar 8 píxeles
ldi
ldi
ldi
ldi
add a, c ; incrementamos una línea
ld e, a
jr c, sigue2
.sigue
djnz draw
ret
sigue2
inc d ; incrementamos D si sale acarrero al incrementar E en 60 bytes
djnz draw
ret
')

Re: Sprites en el modo radastaniano del ZX Uno

Publicado: Lun, 19 Ene 2015, 19:42
por Metalbrain
Lo de sacar ld a,e del bucle creo que no funciona bien... LDI afecta a DE, pero no a A, así que en la suma le estás sumando 60 al valor inicial, no al actual. Y si cambias C por 68 para que se sumen 64, tienes el problema de que si los LDI aumentan el valor de D, este se incrementará 2 veces.

Publicado: Lun, 19 Ene 2015, 20:00
por antoniovillena
Sí, hay que cambiar la constante a 68. Pero creo que funcionará porque para que ldi aumente d el sprite debe estar justo en el borde.

Re: Sprites en el modo radastaniano del ZX Uno

Publicado: Mar, 20 Ene 2015, 17:46
por radastan
Gracias por las anotaciones, serán tomadas en cuenta.

Ya si me la modificáis para que se pueda usar una máscara de bits mejor todavía, yo hasta dentro de unas semanas no tendré tiempo.

Re: Sprites en el modo radastaniano del ZX Uno

Publicado: Mar, 20 Ene 2015, 18:54
por iforeve
$this->bbcode_second_pass_quote('Metalbrain', '
')
Hmmm... no he podido resistirme:



Es lo que se entiende como el "ansia viva". :lol: :lol: :lol: