Karoshi MSX Community
05 de Julio de 2021, 04:02:45 pm *
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.

Ingresar con nombre de usuario, contraseña y duración de la sesión
Noticias:
 
   Inicio   Ayuda Buscar Ingresar Registrarse  
Páginas: [1]
  Imprimir  
Autor Tema: Rutina de Giro de un Byte  (Leído 4515 veces)
0 Usuarios y 1 Visitante están viendo este tema.
j4mk3
Karoshi Maniac
****
Mensajes: 376


MSx Powa!


WWW Email
« : 20 de Diciembre de 2013, 10:29:28 am »

Hola Gurus  Wink

He realizado una rutina de giro de bytes que quería compartir con vosotros. Para ahorrar espacio en ROM, he pensado tener espejos de tiles y sprites. Para ello necesito poder hacer un "espejo" a nivel de bit de un byte.

Esta es la manera en la que se me ha ocurrido. a ver que os parece o si se os ocurre alguna manera de optimizarlo mejor.
Código:
ld A,01101010b ; entro un 6A a modo de ejemplo por el Acumulador
ld C,A ; Me lo guardo en C para su uso

ld E,00010001b ; Preparo una mascara de bits para ir cogiendo de 2 en 2
ld D,0 ; Aquí iré acumulando el resultado
rlc C ; Rotación del byte
ld A,C ; cogemos el byte en su estado actual.
and E ; y le aplicamos la mascara de bits, me quedo 2
or D ; guardamos lo obtenido añadiéndolo a D
ld B,3 ; Preparamos loop para los siguientes bytes que hay que tratar igual
@@loop:
ld D,A ; guardo el resultado parcial en D
rlc E ; Rotamos la mascara
rlc C ; Rotamos dos veces el byte
rlc C
ld A,C ; cogemos el byte en su estado actual.
and E ; y le aplicamos la mascara de bits, me quedo 2
or D ; guardamos lo optenido añadiendolo a D
djnz @@loop
; el resultado final está en Acumulador

Una vez optimizada y consultada con vosotros, lo podré en Snipets.
En línea

---  G Fan  ---  Galious & Gradius  & G Boys   ---
--- Play HANS' ADVENTURE, STAN, THE DREAMER & BITLOGIC ---
SapphiRe_MSX
Visitante
« Respuesta #1 : 20 de Diciembre de 2013, 11:21:12 am »

A ver qué te parece esta:

Código:
espejo: ; Asumimos que en A llega el byte a "espejar"
        ld c,a       ; lo copiamos en c
        ld b,8       ; 8 bits
@@loop: rl c         ; rotamos c hacia la izquierda metiendo los bits en el carry...
        rra          ; ...y vamos metiendo los bits del carry en a hacia la derecha
        djnz @@loop  ; cerramos el bucle
        ret
En línea
Metalbrain
Karoshi Fan
**
Mensajes: 92


Z80jutsushi


« Respuesta #2 : 20 de Diciembre de 2013, 04:01:53 pm »

A ver qué te parece esta

Mejor así:

Código:
espejo: ; Asumimos que en A llega el byte a "espejar"
        ld c,a       ; lo copiamos en c
        ld a,128    ; bit marker, cuando salga marcará el final del bucle
@@loop: rl c         ; rotamos c hacia la izquierda metiendo los bits en el carry...
        rra          ; ...y vamos metiendo los bits del carry en a hacia la derecha
        jr nc @@loop  ; cerramos el bucle
        ret

Un pelín más rápida y no usamos B. Aunque lo más rápido siempre será tener una tabla de 256 bytes con los espejos (alienada a 256 bytes).
En línea
SapphiRe_MSX
Visitante
« Respuesta #3 : 20 de Diciembre de 2013, 05:30:41 pm »

Aunque lo más rápido siempre será tener una tabla de 256 bytes con los espejos (alienada a 256 bytes).

Cierto, pero si lo que quiere es ahorrar sitio en ROM, eso sería perjudicial.
En línea
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« Respuesta #4 : 20 de Diciembre de 2013, 06:06:42 pm »

Aunque lo más rápido siempre será tener una tabla de 256 bytes con los espejos (alienada a 256 bytes).
Cierto, pero si lo que quiere es ahorrar sitio en ROM, eso sería perjudicial.
Se puede generar la tabla en RAM y, cuando no haga falta, reutilizar esa RAM para otros menesteres. No sé cuánto ocupará la rutinilla de generar la tabla, pero no creo que mucho.
Por otra parte, si lo que se necesita es velocidad, siempre se pueden desenrollar los bucles con un coste de 12 bytes (cálculo rápido y puede que inexacto: 2b x 8iteraciones - 2b (cuerpo bucle) - 2b (djnz/jr)). O desenrollarlos sólo parcialmente.
En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« Respuesta #5 : 20 de Diciembre de 2013, 10:57:59 pm »

Mirad la versión optimizada que hay aquí: http://wikiti.brandonw.net/index.php?title=Z80_Routines:Optimized:reverseA
 Wow!
En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
j4mk3
Karoshi Maniac
****
Mensajes: 376


MSx Powa!


WWW Email
« Respuesta #6 : 21 de Diciembre de 2013, 09:48:22 pm »

Esta claro que no controlo como vosotros !  Roll Eyes Huh Madre mia ! que no he pensado bastante.
Sapphire, gracias. La tuya la entiendo a la primera, no se como no se me habia ocurrido antes.  Shocked
Metalbrain,...la leche, esa minioptimización, está muy bien pensada. No sabia que RLA RLCA RRA rotaban sin tocar los flags. Y eso que tengo la guia "del lider de la sociedad". No me habia fijado en la anotación "...salvo flags".
Lo de la tabla...no me termina de convencer, pero es una opción interesante. Gracias theNestruo.
Y ya lo del link megaoptimizado de la muerte es...para sacarse el sombrero.

Muchisimas gracias a todos. No subiré a snipets lo hecho, pq no vale la pena, visto lo visto.
De nuevo gracias, Z80enios !
En línea

---  G Fan  ---  Galious & Gradius  & G Boys   ---
--- Play HANS' ADVENTURE, STAN, THE DREAMER & BITLOGIC ---
Mortimer
Karoshi Lover
***
Mensajes: 216


WWW
« Respuesta #7 : 15 de Enero de 2014, 10:33:14 pm »

Viendo el hilo me he acordado que tenía por algún sitio un par de rutinas para generar la tabla en RAM, optimizadas para tamaño:

Código:
LD HL,mirrortable
LD D,0 ; contador de los 256 bytes
otro: LD B,8 ; Para repetir con los 8 bits
LD A,D ; Byte a tratar
rot: RLCA ; bit 7 a acarreo
RR C ; acarreo a bit 7
DJNZ rot
LD [HL],C ; se guarda rotado
INC HL
INC D ; Contador++
JR NZ,otro ; si no desborda a por el siguiente
Esta primera que ocupa 18 bytes creará la tabla en cualquier posición

Código:
LD HL,mirrortable
otro: LD B,8 ; Para repetir con los 8 bits
LD A,L ; Byte a tratar
rot: RLCA ; bit 7 a acarreo
RR C ; acarreo a bit 7
DJNZ rot
LD [HL],C ; se guarda rotado
INC L ; siguiente byte
JR NZ,otro ; si no desborda a por el siguiente
Y esta segunda 3 bytes más corta crea la tabla con la condición de que el byte bajo del destino sea cero para que luego sea bastante más rápido poder hacer las sustituciones al no tener que hacer una suma de 16 bits para alcanzar el byte rotado..

Y de regalo, la tabla pregenerada para poder ponerla en ROM si vamos sobrados de espacio:

Código:
mirrortable:
db 00000000b
db 10000000b
db 01000000b
db 11000000b
db 00100000b
db 10100000b
db 01100000b
db 11100000b
db 00010000b
db 10010000b
db 01010000b
db 11010000b
db 00110000b
db 10110000b
db 01110000b
db 11110000b
db 00001000b
db 10001000b
db 01001000b
db 11001000b
db 00101000b
db 10101000b
db 01101000b
db 11101000b
db 00011000b
db 10011000b
db 01011000b
db 11011000b
db 00111000b
db 10111000b
db 01111000b
db 11111000b
db 00000100b
db 10000100b
db 01000100b
db 11000100b
db 00100100b
db 10100100b
db 01100100b
db 11100100b
db 00010100b
db 10010100b
db 01010100b
db 11010100b
db 00110100b
db 10110100b
db 01110100b
db 11110100b
db 00001100b
db 10001100b
db 01001100b
db 11001100b
db 00101100b
db 10101100b
db 01101100b
db 11101100b
db 00011100b
db 10011100b
db 01011100b
db 11011100b
db 00111100b
db 10111100b
db 01111100b
db 11111100b
db 00000010b
db 10000010b
db 01000010b
db 11000010b
db 00100010b
db 10100010b
db 01100010b
db 11100010b
db 00010010b
db 10010010b
db 01010010b
db 11010010b
db 00110010b
db 10110010b
db 01110010b
db 11110010b
db 00001010b
db 10001010b
db 01001010b
db 11001010b
db 00101010b
db 10101010b
db 01101010b
db 11101010b
db 00011010b
db 10011010b
db 01011010b
db 11011010b
db 00111010b
db 10111010b
db 01111010b
db 11111010b
db 00000110b
db 10000110b
db 01000110b
db 11000110b
db 00100110b
db 10100110b
db 01100110b
db 11100110b
db 00010110b
db 10010110b
db 01010110b
db 11010110b
db 00110110b
db 10110110b
db 01110110b
db 11110110b
db 00001110b
db 10001110b
db 01001110b
db 11001110b
db 00101110b
db 10101110b
db 01101110b
db 11101110b
db 00011110b
db 10011110b
db 01011110b
db 11011110b
db 00111110b
db 10111110b
db 01111110b
db 11111110b
db 00000001b
db 10000001b
db 01000001b
db 11000001b
db 00100001b
db 10100001b
db 01100001b
db 11100001b
db 00010001b
db 10010001b
db 01010001b
db 11010001b
db 00110001b
db 10110001b
db 01110001b
db 11110001b
db 00001001b
db 10001001b
db 01001001b
db 11001001b
db 00101001b
db 10101001b
db 01101001b
db 11101001b
db 00011001b
db 10011001b
db 01011001b
db 11011001b
db 00111001b
db 10111001b
db 01111001b
db 11111001b
db 00000101b
db 10000101b
db 01000101b
db 11000101b
db 00100101b
db 10100101b
db 01100101b
db 11100101b
db 00010101b
db 10010101b
db 01010101b
db 11010101b
db 00110101b
db 10110101b
db 01110101b
db 11110101b
db 00001101b
db 10001101b
db 01001101b
db 11001101b
db 00101101b
db 10101101b
db 01101101b
db 11101101b
db 00011101b
db 10011101b
db 01011101b
db 11011101b
db 00111101b
db 10111101b
db 01111101b
db 11111101b
db 00000011b
db 10000011b
db 01000011b
db 11000011b
db 00100011b
db 10100011b
db 01100011b
db 11100011b
db 00010011b
db 10010011b
db 01010011b
db 11010011b
db 00110011b
db 10110011b
db 01110011b
db 11110011b
db 00001011b
db 10001011b
db 01001011b
db 11001011b
db 00101011b
db 10101011b
db 01101011b
db 11101011b
db 00011011b
db 10011011b
db 01011011b
db 11011011b
db 00111011b
db 10111011b
db 01111011b
db 11111011b
db 00000111b
db 10000111b
db 01000111b
db 11000111b
db 00100111b
db 10100111b
db 01100111b
db 11100111b
db 00010111b
db 10010111b
db 01010111b
db 11010111b
db 00110111b
db 10110111b
db 01110111b
db 11110111b
db 00001111b
db 10001111b
db 01001111b
db 11001111b
db 00101111b
db 10101111b
db 01101111b
db 11101111b
db 00011111b
db 10011111b
db 01011111b
db 11011111b
db 00111111b
db 10111111b
db 01111111b
db 11111111b

Saludos de 8 bits!
En línea
Páginas: [1]
  Imprimir  
 
Ir a:  

Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.21 | SMF © 2013, Simple Machines XHTML 1.0 válido! CSS válido!