Título: Rutina de Giro de un Byte Publicado por: j4mk3 en 20 de Diciembre de 2013, 10:29:28 am Hola Gurus ;)
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. Título: Re:Rutina de Giro de un Byte Publicado por: SapphiRe_MSX en 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 Título: Re:Rutina de Giro de un Byte Publicado por: Metalbrain en 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). Título: Re:Rutina de Giro de un Byte Publicado por: SapphiRe_MSX en 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. Título: Re:Rutina de Giro de un Byte Publicado por: theNestruo en 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.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. Título: Re:Rutina de Giro de un Byte Publicado por: theNestruo en 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:: Título: Re:Rutina de Giro de un Byte Publicado por: j4mk3 en 21 de Diciembre de 2013, 09:48:22 pm Esta claro que no controlo como vosotros ! ::) ??? 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. :o 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 ! Título: Re:Rutina de Giro de un Byte Publicado por: Mortimer en 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 Esta primera que ocupa 18 bytes creará la tabla en cualquier posiciónLD 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 Código: LD HL,mirrortable 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..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 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! |