Exomizer 2, rutinas actualizadas

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
Metalbrain
Forero habitual
Forero habitual
Mensajes: 151
Registrado: Mar 30 Oct , 2007 1:45 pm
Ubicación: Sevilla

Exomizer 2, rutinas actualizadas

Mensajepor Metalbrain » Mar 17 Ene , 2012 7:00 pm

Veo que no hay un hilo dedicado a Exomizer, así que aprovechando que hay novedades, pues lo creo ahora:

Señoras y señores, con ustedes el método de compresión que vence con claridad tanto al de aPLib como al de pucrunch: exomizer 2.

https://bitbucket.org/magli143/exomizer/wiki/Home

Como no había descompresor para Z80, lo porté yo, y además hice un optimizador que coge la salida del exomizer, le quita 2 bits inútiles y le reordena los bits para que se puedan leer un poco más rápido con el Z80. Hace escasos días Antonio Villena ha optimizado los descompresores de forma que ahora son más rápidos, y de paso les ha recortado unos cuantos bytes.

Los tamaños de los descompresores varían entre 163-187 bytes. La rutina descompresora necesita una tabla de 156 bytes, que puede ser desechada tras la descompresión, así que si la ponemos en un buffer no debería suponer ningún gasto extra. De registros alternativos solo utiliza el AF'.

http://www.speccy.org/metalbrain/exo_v4.zip

En la carpeta /normal están las versiones que funcionan directamente con la salida que genera exomizer al hacer:

exomizer raw -o salida entrada

En /optimized están las que funcionan con la salida optimizada, la cual se genera haciendo:

exomizer raw -o temporal entrada
exoopt temporal salida

exoopt es el optimizador, el ejecutable Windows está presente en optimized/bin y su código fuente para otros sistemas en optimized/src

Las rutinas _simple necesitan que la tabla esté alineada a un múltiplo de 256, y no soportan cadenas de literales, que suele ser raro que aparezcan y además se pueden desactivar con la opción -c de exomizer.

Avatar de Usuario
Artaburu
Trasteador
Trasteador
Mensajes: 8419
Registrado: Vie 07 Oct , 2005 6:18 pm
Ubicación: En tu pantalla

Re: Exomizer 2, rutinas actualizadas

Mensajepor Artaburu » Mar 17 Ene , 2012 7:07 pm

Yo me lo guardo y, a partir de ahora, será mi compresor de cabecera para CPC. ¡Muchas gracias por compartirlo!
Salu2,
Arta

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

Re: Exomizer 2, rutinas actualizadas

Mensajepor gg » Sab 21 Ene , 2012 11:59 am

Estupendo. Si no me falla la memoria, yo venía usando la versión 2. Voy a comprobarlo y descargo esta otra.
Saludos,
gg.

Avatar de Usuario
Metalbrain
Forero habitual
Forero habitual
Mensajes: 151
Registrado: Mar 30 Oct , 2007 1:45 pm
Ubicación: Sevilla

Re: Exomizer 2, rutinas actualizadas

Mensajepor Metalbrain » Mié 25 Jul , 2012 9:07 pm

Ops! :oops:

Metí la pata al volver a meter los comentarios en el código nuevo, incluyendo en la rutina normal (no simple) una línea de la versión antigua que jode toda la descompresión. Ya está corregido, os lo podeis volver a bajar en el mismo enlace:
http://www.speccy.org/metalbrain/exo_v4.zip

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

Re: Exomizer 2, rutinas actualizadas

Mensajepor gg » Vie 27 Jul , 2012 9:12 pm

Estupendo, habrá que darle uso al invento.
Saludos,
gg.

Urusergi
Forum Addict
Forum Addict
Mensajes: 380
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Exomizer 2, rutinas actualizadas

Mensajepor Urusergi » Mié 31 Oct , 2012 9:49 pm

Hola!

Tenía ganas de estudiar este proyecto y por fin he tenido tiempo. La verdad es que estoy alucinando por partida doble: =D> por la inventiva de Magnus y por las rutinas creadas por Metalbrain y optimizaciones posteriores de Antonio.

El caso es que, a pesar de la dificultad, he logrado encontrar una pequeña mejora de 1 byte en la rutina descompresora. Estoy usando la óptima simple pero imagino que se podrá aplicar a las otras (no lo he mirado).

Consiste en cortar la primera línea de la subrutina exo_getpair (ld iyl, c) y pegarla justo antes del primer call exo_getpair , y por otro lado sustituir el código:

Código: Seleccionar todo

ex af, af'
ld a, e
add a, c
ld c, a
ex af, af'
por este otro:

Código: Seleccionar todo

ld iyl,e
add iy,bc
Ahora estoy tratando de optimizar el código:

Código: Seleccionar todo

ex af, af'
ld a, b
sub 4
and 15
jr nz, exo_node1
ld de, 1 ;DE=b2
exo_node1: ld c, 16
ex af, af'
con la idea de eliminar las otras dos instrucciones ex af, af' (ya se que se pueden sustituir por push af y pop af) y lograr un ahorro adicional de dos bytes correspondientes al di y ei necesarios al llamar a la subrutina y evitar asi mensajes como el de la cpcwiki:
Exomizer can sometimes fail to decompress files correctly for no apparent reason, causing the CPC to crash. Unfortunately there is no known way to overcome this problem, other than to use a different compressor.
[-X

Un saludo

Urusergi
Forum Addict
Forum Addict
Mensajes: 380
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Exomizer 2, rutinas actualizadas

Mensajepor Urusergi » Vie 02 Nov , 2012 4:32 pm

8-[ Bueno, me ha costado más de la cuenta pero por fin he dado con ello:

Código: Seleccionar todo

ld ixl, 1
exo_initbits: ld c, 16
dec ixl
jr nz, exo_get4bits
ld de, 1
ld ixl,c
He aprovechado el registro c, que al tener el valor 16 me viene genial para usarlo como inicializador del contador ixl, y de esta manera logro que ocupe el mismo número de bytes que la rutina original (pero gana velocidad, aunque no sea importante en este caso). Lo verdaderamente importante es el ahorro "externo" de 2 bytes (DI-EI) al no tener que depender ya del registro A' de modo que ya es compatible 100% con el Amstrad CPC sin tener que añadir código antes de la llamada \:D/

Un saludo.

Avatar de Usuario
Artaburu
Trasteador
Trasteador
Mensajes: 8419
Registrado: Vie 07 Oct , 2005 6:18 pm
Ubicación: En tu pantalla

Re: Exomizer 2, rutinas actualizadas

Mensajepor Artaburu » Sab 03 Nov , 2012 12:48 am

Great news! Porque así, efectivamente no desactivaríamos las interrupciones y podríamos reproducir música durante la descompresión. Me lo apunto para cambiarlo en las librerías para C, con tu permiso, claro ;)
Salu2,
Arta

Urusergi
Forum Addict
Forum Addict
Mensajes: 380
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Exomizer 2, rutinas actualizadas

Mensajepor Urusergi » Mar 06 Nov , 2012 1:03 am

Great news! Porque así, efectivamente no desactivaríamos las interrupciones y podríamos reproducir música durante la descompresión. Me lo apunto para cambiarlo en las librerías para C, con tu permiso, claro ;)
Hombreeeeee, Arta! tú no tienes que pedir permiso para nada, faltaría más! :wink:

¿Cuál es la rutina que has metido en tu librería? ¿la deexo_simple.asm de la carpeta optimized? si no es ésta asegúrate de que las modificaciones son compatibles...

Un saludo.

Urusergi
Forum Addict
Forum Addict
Mensajes: 380
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Exomizer 2, rutinas actualizadas

Mensajepor Urusergi » Jue 08 Nov , 2012 5:06 pm

Otra optimización, aunque sea un adorno más que otra cosa:

Código: Seleccionar todo

ld (iy+52), e
ld (iy+104), d ;base[i]=b2
add hl, de
ex de, hl
inc iy
pop hl
djnz exo_initbits
La instrucción inc iy se puede sustituir por inc iyl para tardar 104 ciclos menos en generar el buffer (en el cpc puede que no haya ahorro alguno)

Y por otro lado una modificación de posición:

Código: Seleccionar todo

ld de, 512+48 ;1?
inc b
djnz exo_dontgo
dec c
La instrucción ld de, 512+48 es mejor que esté situada justo después del djnz. De esta manera se le gana 10 ciclos cada vez que la longitud sea superior a 255 (si, un caso raro pero posible)

Un saludo.

Urusergi
Forum Addict
Forum Addict
Mensajes: 380
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Exomizer 2, rutinas actualizadas

Mensajepor Urusergi » Vie 09 Nov , 2012 8:55 pm

Y oooooooootra importante optimización, esta vez por parte del maestro Antonio Villena:

Código: Seleccionar todo

ld ixl, 1

exo_initbits: dec ixl
ld c, 16
jr NZ, exo_get4bits
ld de, 1 ;DE=b2
ld ixl,c
por este otro:

Código: Seleccionar todo

cp a
defb &C2
exo_initbits: dec ixl
ld c, 16
jr NZ, exo_get4bits
ld de, 1 ;DE=b2
ld ixl,c
Con esto ganamos 1 byte más, todo un logro teniendo en cuenta lo optimizado que ya estaba =D>

Un saludo.

Avatar de Usuario
Artaburu
Trasteador
Trasteador
Mensajes: 8419
Registrado: Vie 07 Oct , 2005 6:18 pm
Ubicación: En tu pantalla

Re: Exomizer 2, rutinas actualizadas

Mensajepor Artaburu » Vie 09 Nov , 2012 10:03 pm

Es increíble que todavía se pueda seguir optimizando. Casi te sabrás de memoria el código :D
Salu2,
Arta

antoniovillena
Forero habitual
Forero habitual
Mensajes: 115
Registrado: Mar 26 Abr , 2011 9:25 pm

Re: Exomizer 2, rutinas actualizadas

Mensajepor antoniovillena » Sab 10 Nov , 2012 1:36 am

Todo el mérito es de Urusergi. A parte de que ya no empleamos el registro AF' y es unos cuantos ciclos más rápida, la rutina ha pasado de 163 bytes a 160 (la optimizada simple, las otras también reducen 3 bytes cada una). Me dejé atrás otro byte que era evidente, el código final sería este:

Código: Seleccionar todo

ld iy, exo_mapbasebits
ld a, 128
ld b, 52
push de
cp a
exo_initbits:
ld c, 16
jr nz, exo_get4bits
ld de, 1
ld ixl, c
exo_get4bits:
call exo_getbit
rl c
jr nc, exo_get4bits
ld (iy+0), c ;bits[i]=b1
push hl
ld hl, 1
defb 210 ;3 bytes nop (JP NC)
exo_setbit:
add hl, hl
dec c
jr nz, exo_setbit
exo_one:
ld (iy+52), e
ld (iy+104), d ;base[i]=b2
add hl, de
ex de, hl
inc iyl
pop hl
dec ixl
djnz exo_initbits
pop de
exo_literalcopy:
ldi
exo_mainloop:
call exo_getbit ;literal?
jr c, exo_literalcopy
ld c, 255
exo_getindex:
inc c
call exo_getbit
jr nc, exo_getindex
bit 4, c
ret nz
push de
ld iyl, c
call exo_getpair
push bc
pop ix
inc b
djnz exo_dontgo
ld de, 512+48 ;1?
dec c
jr z, exo_goforit
dec c ;2?
exo_dontgo:
ld de, 1024+32
jr z, exo_goforit
ld e, 16
exo_goforit:
call exo_getbits
ld iyl, e
add iy, bc
call exo_getpair ;bc=offset
pop de ;de=destination
push hl
ld h, d
ld l, e
sbc hl, bc ;hl=origin
push ix
pop bc ;bc=lenght
ldir
pop hl ;Keep HL, DE is updated
jr exo_mainloop ;Next!

exo_getpair:
ld d, (iy+0)
call exo_getbits
push hl
ld l, (iy+52)
ld h, (iy+104)
add hl, bc ;Always clear C flag
ld b, h
ld c, l
pop hl
ret

exo_getbits:
ld bc, 0 ;get D bits in BC
exo_gettingbits:
dec d
ret m
call exo_getbit
rl c
rl b
jr exo_gettingbits

exo_getbit:
add a, a
ret nz
ld a, (hl)
inc hl
adc a, a
ret
Si me estás leyendo, Metalbrain, actualiza tus rutinas y dale un aviso a Magnus. Que no se te olvide poner a Urusergi en los créditos.

antoniovillena
Forero habitual
Forero habitual
Mensajes: 115
Registrado: Mar 26 Abr , 2011 9:25 pm

Re: Exomizer 2, rutinas actualizadas

Mensajepor antoniovillena » Mar 13 Nov , 2012 11:15 am

Se añaden 2 mejoras. Por un lado Urusergi ha conseguido mejorar casi un 20% la velocidad de la rutina con un pequeño cambio que sólo implica 2 bytes más de código.
Se trata de sustituir todos los call exo_getbit por:
add a,a
call z,exo_getbit

Y en la subrutina, como te imaginarás, hay que eliminar el add a,a y el ret nz
Por otro lado he conseguido optimizar 1 byte, cambiando ésto:

Código: Seleccionar todo

pop de ;de=destination
push hl
ld h, d
ld l, e
por esto otro:

Código: Seleccionar todo

ex (sp), hl
ld d, h
ld e, l
La rutina simple optimizada ahora ocupa 161 bytes (159 bytes si no te parece bien la versión rápida) y sería ésta:

Código: Seleccionar todo

ld iy, exo_mapbasebits
ld a, 128
ld b, 52
push de
cp a
exo_initbits:
ld c, 16
jr nz, exo_get4bits
ld de, 1
ld ixl, c
exo_get4bits:
add a, a
call z, exo_getbit
rl c
jr nc, exo_get4bits
ld (iy+0), c ;bits[i]=b1
push hl
ld hl, 1
defb 210 ;3 bytes nop (JP NC)
exo_setbit:
add hl, hl
dec c
jr nz, exo_setbit
exo_one:
ld (iy+52), e
ld (iy+104), d ;base[i]=b2
add hl, de
ex de, hl
inc iyl
pop hl
dec ixl
djnz exo_initbits
pop de
exo_literalcopy:
ldi
exo_mainloop:
add a, a
call z, exo_getbit ;literal?
jr c, exo_literalcopy
ld c, 255
exo_getindex:
inc c
add a, a
call z, exo_getbit
jr nc, exo_getindex
bit 4, c
ret nz
push de
ld iyl, c
call exo_getpair
push bc
pop ix
inc b
djnz exo_dontgo
ld de, 512+48 ;1?
dec c
jr z, exo_goforit
dec c ;2?
exo_dontgo:
ld de, 1024+32
jr z, exo_goforit
ld e, 16
exo_goforit:
call exo_getbits
ld iyl, e
add iy, bc
call exo_getpair ;bc=offset
ex (sp), hl
ld d, h
ld e, l
sbc hl, bc ;hl=origin
push ix
pop bc ;bc=lenght
ldir
pop hl ;Keep HL, DE is updated
jr exo_mainloop ;Next!

exo_getpair:
ld d, (iy+0)
call exo_getbits
push hl
ld l, (iy+52)
ld h, (iy+104)
add hl, bc ;Always clear C flag
ld b, h
ld c, l
pop hl
ret

exo_getbits:
ld bc, 0 ;get D bits in BC
exo_gettingbits:
dec d
ret m
add a, a
call z, exo_getbit
rl c
rl b
jr exo_gettingbits

exo_getbit:
ld a, (hl)
inc hl
adc a, a
ret

Avatar de Usuario
Artaburu
Trasteador
Trasteador
Mensajes: 8419
Registrado: Vie 07 Oct , 2005 6:18 pm
Ubicación: En tu pantalla

Re: Exomizer 2, rutinas actualizadas

Mensajepor Artaburu » Mar 13 Nov , 2012 12:47 pm

Se añaden 2 mejoras. Por un lado Urusergi ha conseguido mejorar casi un 20% la velocidad de la rutina con un pequeño cambio que sólo implica 2 bytes más de código.
:shock: :shock: =D> =D>
Salu2,
Arta


¿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