Registrarse    Identificarse    Foro    FAQ

Índice general » General » Programación | Programming




Nuevo tema Responder al tema  [ 3 mensajes ] 
Autor Mensaje
 Asunto: Compresor/descompresor RLE nativo para Z80
 Nota Publicado: 03 Feb 2010 13:43 
Desconectado
16 bits
16 bits
Avatar de Usuario

Registrado: 15 Ene 2006 21:49
Mensajes: 94
Ubicación: Ciudad Real
Despues de leer el articulo del RLE de santiago romero, he reescrito el codigo de la rutina descompresora y he creado la rutina compresora.
He realizado la compresion de la rom de 48K, y posterior descompresion y salen identicas.
Hay un pequeño truquito con el LDI y el RET PO (un flash no muy usado, pero que usa LDI para indicar BC=#0000) y me he ahorrado algunos bytes
rutina compresora 62 bytes
rutina descompresora 26 bytes

Código:
;; Creada por Z80user
;; Compresor / Descompresor RLE
;; Comprime y Descomprime un bloque de datos RLE de memoria a memoria.
;;
;; Entrada a la rutina COMPRESORA:
;; HL = destino de los datos RLE.
;; IX = datos a comprimir
;; BC = tamaño de los datos a comprimir.
;; Salida
;; AF,DE   desconocido
;; HL = HL+longitud de los datos comprimidos
;; IX = IX+BC
;;
;; Entrada a la rutina DESCOMPRESORA:
;; HL = dirección origen de los datos RLE.
;; DE = destino donde descomprimir los datos.
;; BC = tamaño de los datos a comprimir.
;; Salida
;; AF,DE   desconocido
;; HL = HL+longitud de los datos descomprimidos
;; DE = DE+BC
;; 26 + 62 = 88
//-------------
           org 16384
RLE_descompress
RLE_dec_loop
             LD   A,[HL]      ; Leemos 1 byte
             CP   A,192
               JR   NC,RLE_dec   ; si byte > 192 = está comprimido
test_end     LDI         ; Copiamos 1 byte en crudo
      RET   PO      ; Volvemos si hemos terminado
             JR   RLE_dec_loop   ; Repetimos el bucle
RLE_dec                        ; bucle para descompresión RLE
      INC   HL              ; Nos colocamos en el valor
      AND   A,#3F
      JR   Z,test_end   ; Si 192, es dato en crudo
      PUSH   BC
      LD   B,A         ; B= numero de repeticiones
        LD   A,[HL]
bucle      LD   [DE],A      ; \
      INC   DE              ;  Bucle de escritura B veces
      DJNZ   bucle           ; /
      POP   BC
      DEC   BC              ; Ajustamos el contador al usar RLE
      JR   test_end   ; Copiamos 1 byte mas
//---------------
RLE_Comprimir
byte_1      LD   E,[IX+#00]      ; leer byte
      INC   IX              ; incrementar posicion
      DEC   BC              ; descontar contador
      LD   A,E      ;
byte_2      CP   A,#C0      ; Si es un codigo RLE
      JR   NC,RLE_compress   ;  tratar como RLE
      CALL   get_byte   ; tomar el 2º byte
      JR   Z,ultimo_byte   ; falta escribir el ultimo byte
      CP   A,E             ;
      JR   Z,RLE_compress2   ; usar compresion RLE si son identicos
      LD   [HL],E          ; son distintos, escribir el byte anterior
      INC   HL              ;
      LD   E,A             ; recuperar el ultimo byte leido
      JR   byte_2      ; continuar con la compresion
ultimo_byte   LD   [HL],E          ; escribir el ultimo byte
      INC   HL              ;
      RET         ; salir
RLE_compress2   LD   D,#C1           ; eran identicos, empezar, con 2
      JR   RLE_Repetido
RLE_compress   LD   D,#C0      ; era un valor RLE original
RLE_Repetido   CALL   get_byte   ; Obtener otro byte
      JR   Z,RLE_distinto   ; Escribir el valor RLE si no hya mas bytes
      CP   A,E      ; Comprobar si es identico
      JR   NZ,RLE_distinto   ; Se encontro un byte distinto
      INC   D      ; incrementar el contador de repeticiones
      JR   NZ,RLE_Repetido   ; Otro byte identico
      DEC   D      ; Se acabo el contador de repeticiones
RLE_distinto   LD   [HL],D      ; \
      INC   HL              ;  \ escribir valor RLE
byte_simple   LD   [HL],E      ;  /
      INC   HL      ; /
      LD   E,A             ; Recuperar el ultimo byte distinto
      JR   byte_2      ; segir comprimiendo
get_byte   LD   A,B      ; \
      OR   A,C             ;  Comprobar si es el ultimo byte
      RET   Z               ; /
      DEC   BC              ; descontar contador
      LD   A,[IX+#00]      ; leer byte
      INC   IX              ; incrementar posicion
      RET                     ;

La rutina la probe con la rom, porque era lo que mas a mano tenia, esta en todos los emuladores, y es bastante aleatoria, como para por lo menos que el test diga, que el programa es fiable.

Una posible mejora es indicar cuantos bytes hay en crudo, no solo los comprimidos, con un byte extra, pudiendo ahorrar algunos bytes, si los datos son mayores o iguales que el #C0


Arriba 
 Perfil  
 
 Asunto: Re: Compresor/descompresor RLE nativo para Z80
 Nota Publicado: 03 Feb 2010 16:27 
Desconectado
128 bits
128 bits
Avatar de Usuario

Registrado: 16 Oct 2005 15:56
Mensajes: 1741
Ubicación: Sevilla
Recorto 2 bytes a la rutina descompresora:

Código:
RLE_descompress:
RLE_dec_loop:   LD      A,[HL]          ; Leemos 1 byte
                SUB     192
                JR      NC,RLE_dec      ; si byte > 192 = está comprimido
test_end:       LDI                     ; Copiamos 1 byte en crudo
                RET     PO              ; Volvemos si hemos terminado
                JR      RLE_dec_loop    ; Repetimos el bucle
RLE_dec:                                ; bucle para descompresión RLE
                INC     HL              ; Nos colocamos en el valor
                JR      Z,test_end      ; Si 192, es dato en crudo
                PUSH    BC
                LD      B,A             ; B= numero de repeticiones
                LD      A,[HL]
bucle:          LD      [DE],A          ; \
                INC     DE              ;  Bucle de escritura B veces
                DJNZ    bucle           ; /
                POP     BC
                DEC     BC              ; Ajustamos el contador al usar RLE
                JR      test_end        ; Copiamos 1 byte mas

_________________
SevenuP se escribe con u minúscula y P mayúscula.

I need Speed - Kein Aufruf zu Drogenkonsum.


Arriba 
 Perfil  
 
 Asunto: Re: Compresor/descompresor RLE nativo para Z80
 Nota Publicado: 05 Feb 2010 01:10 
Desconectado
16 bits
16 bits
Avatar de Usuario

Registrado: 15 Ene 2006 21:49
Mensajes: 94
Ubicación: Ciudad Real
Metalbrain escribió:
Recorto 2 bytes a la rutina descompresora:

](*,) y 7 t-States :-)
creo que es de las pocas rutinas que no he mirado lo que tardan, pero como el RLE no es gran cosa.
he pensado en hacer una version V2, para que no tenga el problema de engordar tanto si hay muchos numeros altos sin repeticiones. en el codigo del Z80 el rango que menos se usa debe de ser del 64 al 127 (LD r,r)


Arriba 
 Perfil  
 
Mostrar mensajes previos:  Ordenar por  
 
Nuevo tema Responder al tema  [ 3 mensajes ] 

Índice general » General » Programación | Programming


¿Quién está conectado?

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

 
 

 
No puede abrir nuevos temas en este Foro
No puede responder a temas en este Foro
No puede editar sus mensajes en este Foro
No puede borrar sus mensajes en este Foro
No puede enviar adjuntos en este Foro

Saltar a:  
cron
 
Thermomix | Thermomix 31