cursos:ensamblador:compresion_rle

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
cursos:ensamblador:compresion_rle [18-01-2024 09:54] – [Programa de ejemplo de descompresión] sromerocursos:ensamblador:compresion_rle [19-01-2024 12:35] (actual) – [Programa de ejemplo de descompresión] sromero
Línea 345: Línea 345:
 RLE_decompress: RLE_decompress:
  
-RLE_dec_loop+rle_dec_loop
-    LD A, (HL)                     ; leemos un byte+    ld a, (hl)                     ; leemos un byte
  
-    CP 192 +    cp 192 
-    JP NCRLE_dec_compressed     ; si byte > 192 = está comprimido +    jp ncrle_dec_compressed     ; si byte > 192 = está comprimido 
-    LD (DE),                    ; si no está comprimido, escribirlo +    ld (de),                    ; si no está comprimido, escribirlo 
-    INC DE +    inc de 
-    INC HL +    inc hl 
-    DEC BC+    dec bc
  
-RLE_dec_loop2+rle_dec_loop2
-    LD AB +    ld ab 
-    OR C +    or c 
-    JR NZRLE_dec_loop +    jr nzrle_dec_loop 
-    RET                           ; miramos si hemos acabado+    ret                           ; miramos si hemos acabado
  
-RLE_dec_compressed:               ; bucle para descompresión +rle_dec_compressed:               ; bucle para descompresión 
-    PUSH BC +    push bc 
-    AND 63                        ; cogemos el numero de repeticiones +    and %00111111                 ; cogemos el numero de repeticiones 
-    LD B                      ; lo salvamos en B +    ld b                      ; lo salvamos en B 
-    INC HL                        ; y leemos otro byte (dato a repetir) +    inc hl                        ; y leemos otro byte (dato a repetir) 
-    LD A, (HL)+    ld a, (hl)
  
-RLE_dec_loop3+rle_dec_loop3
-    LD (DE),                    ; bucle de escritura del dato B veces +    ld (de),                    ; bucle de escritura del dato B veces 
-    INC DE +    inc de 
-    DJNZ RLE_dec_loop3 +    djnz rle_dec_loop3 
-    INC HL +    inc hl 
-    POP BC                        ; recuperamos BC +    pop bc                        ; recuperamos BC 
-    DEC BC                        ; Este DEC BC puede hacer BC=0 si los datos+    dec bc                        ; Este dec bc puede hacer BC=0 si los datos
                                   ; RLE no son correctos. Cuidado (mem-smashing).                                   ; RLE no son correctos. Cuidado (mem-smashing).
-    DEC BC +    dec bc 
-    JR RLE_dec_loop2 +    jr rle_dec_loop2 
-    RET+    ret
 </code> </code>
  
Línea 567: Línea 567:
  
 \\  \\ 
-  * **Método INCBIN**: Incluyendo el binario directamente en Pasmo con la directiva ''INCBIN'' asociándole una etiqueta para poder hacer referencia a él:\\ <code>+  * **Método INCBIN**: Incluyendo el binario directamente en Pasmo con la directiva ''INCBIN'' asociándole una etiqueta para poder hacer referencia a él:\\ \\ <code>
 Datos_Comprimidos: Datos_Comprimidos:
    INCBIN "fichero.rle"    INCBIN "fichero.rle"
Línea 573: Línea 573:
 \\  \\ 
  
-  * **Método BIN2CODE**: Convirtiendo los datos binarios a "texto" con una utilidad como BIN2C o BIN2CODE (las tenéis disponibles como descargas en la sección de ficheros). Estas utilidades para PC (Linux, MAC, DOS/Windows) toman un fichero binario y lo convierten a datos listos para incluir en nuestros programas:\\ <code>+  * **Método BIN2CODE**: Convirtiendo los datos binarios a "texto" con una utilidad como BIN2C o BIN2CODE (las tenéis disponibles como descargas en la sección de ficheros). Estas utilidades para PC (Linux, MAC, DOS/Windows) toman un fichero binario y lo convierten a datos listos para incluir en nuestros programas:\\ \\ <code>
 [sromero@compiler:~rlezx]$ bin2code sokoban.rle datos.asm a [sromero@compiler:~rlezx]$ bin2code sokoban.rle datos.asm a
 BIN2CODE v1.0             By NoP of Compiler SoftWare BIN2CODE v1.0             By NoP of Compiler SoftWare
Línea 581: Línea 581:
  
 [sromero@compiler:~rlezx]$ cat datos.asm [sromero@compiler:~rlezx]$ cat datos.asm
-;  File created with  BIN2CODE  v1.0  by  NOP of Compiler SoftWare+;  File created with  BIN2CODE  v1.0  by  nop of Compiler SoftWare
  
 BINDATASIZE   EQU   2571 BINDATASIZE   EQU   2571
Línea 611: Línea 611:
  
     ; Cargamos los datos y preparamos nuestra rutina     ; Cargamos los datos y preparamos nuestra rutina
-    LD HL, Pantalla_Comprimida +    ld hl, Pantalla_Comprimida 
-    LD DE, 16384 +    ld de, 16384 
-    LD BC, 2571 +    ld bc, 2571 
-    CALL RLE_decompress+    call RLE_decompress
  
 Wait_For_Keys_Pressed:         ; Bucle para esperar pulsación de tecla Wait_For_Keys_Pressed:         ; Bucle para esperar pulsación de tecla
-    XOR A +    xor a 
-    IN A, (254+    in a, ($fe
-    OR 224 +    or %11100000 
-    INC A +    inc a 
-    JR Z, Wait_For_Keys_Pressed +    jr z, Wait_For_Keys_Pressed 
-    RET                          ; Fin del programa+    ret                          ; Fin del programa
  
-;+Aquí incluiremos el código de la rutina RLE_decompress 
-;; RLE_decompress +;; --- RLE_decompress ---
-;; Descomprime un bloque de datos RLE de memoria a memoria. +
-;; +
-;; Entrada a la rutina+
-;; +
-;; HL = dirección origen de los datos RLE. +
-;; DE = destino donde descomprimir los datos. +
-;; BC = tamaño de los datos comprimidos. +
-;; +
-RLE_decompress: +
- +
-RLE_dec_loop: +
-    LD A, (HL)                         leemos un byte +
- +
-    CP 192 +
-    JP NC, RLE_dec_compressed          si byte > 192 = está comprimido +
-    LD (DE), A                         ; si no está comprimido, escribirlo +
-    INC DE +
-    INC HL +
-    DEC BC +
- +
-RLE_dec_loop2: +
-    LD A, B +
-    OR C +
-    JR NZ, RLE_dec_loop +
-    RET                                 ; miramos si hemos acabado +
- +
-RLE_dec_compressed:                    ; bucle para descompresión +
-    PUSH BC +
-    AND 63                              ; cogemos el numero de repeticiones +
-    LD B, A                             ; lo salvamos en B +
-    INC HL                              ; y leemos otro byte (dato a repetir) +
-    LD A, (HL) +
- +
-RLE_dec_loop3: +
-    LD (DE), A                          ; bucle de escritura del dato B veces +
-    INC DE +
-    DJNZ RLE_dec_loop3 +
-    INC HL +
-    POP BC                              ; recuperamos BC +
-    DEC BC                              ; Este DEC BC puede hacer BC=0 si los datos +
-                                        ; RLE no correctos. Cuidado (mem-smashing). +
-    DEC BC +
-    JR RLE_dec_loop2 +
-    RET+
  
 ; Aquí viene nuestra pantalla comprimida con RLE. ; Aquí viene nuestra pantalla comprimida con RLE.
 ; Hay que darse cuenta de que está fuera de todo ; Hay que darse cuenta de que está fuera de todo
-; código ejecutable, es decir, el RET de la rutina +; código ejecutable, es decir, el ret de la rutina 
-; principal y el RET de las subrutina de RLE_Decompress+; principal y el ret de las subrutina de RLE_Decompress
 ; hacen que nunca se llegue a este punto para ejecución. ; hacen que nunca se llegue a este punto para ejecución.
  
Línea 692: Línea 648:
 ===== Rutina optimizada por Z80user ===== ===== Rutina optimizada por Z80user =====
  
- El usuario Z80user, en los foros oficiales de Speccy.org, nos aporta una modificación de nuestra rutina original y una rutina compresora nativa:+ El usuario Z80user,  en los foros oficiales de Speccy.org,  nos aporta una modificación de nuestra rutina original y una rutina compresora nativa:
  
 \\  \\ 
-//He leído el articulo del RLE, 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 descompresión y salen identicas. He utilizado 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 (compresora 62 bytes, descompresora 26 bytes).//+//He leído el articulo del RLE,  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 descompresión y salen identicas. He utilizado 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 (compresora 62 bytes,  descompresora 26 bytes).//
 \\  \\ 
  
Línea 708: Línea 664:
 ;; BC = tamaño de los datos a comprimir. ;; BC = tamaño de los datos a comprimir.
 ;; Salida ;; Salida
-;; AF,DE   desconocido+;; AF, DE   desconocido
 ;; HL = HL+longitud de los datos comprimidos ;; HL = HL+longitud de los datos comprimidos
 ;; IX = IX+BC ;; IX = IX+BC
Línea 717: Línea 673:
 ;; BC = tamaño de los datos a comprimir. ;; BC = tamaño de los datos a comprimir.
 ;; Salida ;; Salida
-;; AF,DE   desconocido+;; AF, DE   desconocido
 ;; HL = HL+longitud de los datos descomprimidos ;; HL = HL+longitud de los datos descomprimidos
 ;; DE = DE+BC ;; DE = DE+BC
Línea 723: Línea 679:
 //------------- //-------------
  
-RLE_descompress +RLE_descompress: 
-RLE_dec_loop +rle_dec_loop: 
-          LD   A,[HL]             ; Leemos 1 byte +          ld a(hl)                     ; Leemos 1 byte 
-          CP   A,192 +          cp a, 192 
-          JR   NC,RLE_dec         ; si byte > 192 = está comprimido +          jr ncrle_dec                 ; si byte > 192 = está comprimido 
-test_end  LDI                     ; Copiamos 1 byte en crudo +rle_test_end: 
-          RET   PO                ; Volvemos si hemos terminado +          ldi                            ; Copiamos 1 byte en crudo 
-          JR   RLE_dec_loop       ; Repetimos el bucle +          ret pO                         ; Volvemos si hemos terminado 
-RLE_dec                           ; bucle para descompresión RLE +          jr rle_dec_loop                ; Repetimos el bucle 
-          INC   HL                ; Nos colocamos en el valor +rle_dec:                                 ; bucle para descompresión RLE 
-          AND   A,#3F +          inc hl                         ; Nos colocamos en el valor 
-          JR   Z,test_end         ; Si 192, es dato en crudo +          and a$3f 
-          PUSH   BC +          jr zrle_test_end             ; Si 192,  es dato en crudo 
-          LD   B,A                ; B= numero de repeticiones +          push bc 
-          LD   A,[HL] +          ld ba                        ; B= numero de repeticiones 
-bucle     LD   [DE],A             ; \ +          ld a(hl) 
-          INC   DE                ;  Bucle de escritura B veces +rle_bucle: 
-          DJNZ   bucle            ; / +          ld (de)a                     ; \ 
-          POP   BC +          inc de                         ;  Bucle de escritura B veces 
-          DEC   BC                ; Ajustamos el contador al usar RLE +          djnz rle_bucle                 ; / 
-          JR   test_end           ; Copiamos 1 byte mas+          pop bc 
 +          dec bc                         ; Ajustamos el contador al usar RLE 
 +          jr rle_test_end                ; Copiamos 1 byte mas
  
  
 //--------------- //---------------
-RLE_Comprimir +RLE_Comprimir: 
-byte_1 +rle_byte_1: 
-          LD   E,[IX+#00]         ; leer byte +          ld e(ix+$00)                 ; leer byte 
-          INC   IX                ; incrementar posicion +          inc ix                         ; incrementar posicion 
-          DEC   BC                ; descontar contador +          dec bc                         ; descontar contador 
-          LD   A,E                ; +          ld ae 
-byte_2 +rle_byte_2: 
-          CP   A,#C0              ; Si es un codigo RLE +          cp a, #C0                      ; Si es un codigo RLE 
-          JR   NC,RLE_compress    ;  tratar como RLE +          jr ncrle_compress            ;  tratar como RLE 
-          CALL   get_byte         ; tomar el 2º byte +          call rle_get_byte              ; tomar el 2º byte 
-          JR   Z,ultimo_byte      ; falta escribir el ultimo byte +          jr zrle_ultimo_byte          ; falta escribir el ultimo byte 
-          CP   A,E                ; +          cp a, E 
-          JR   Z,RLE_compress2    ; usar compresion RLE si son identicos +          jr zrle_compress2            ; usar compresion RLE si son identicos 
-          LD   [HL],E             ; son distintos, escribir el byte anterior +          ld (hl)e                     ; son distintos,  escribir el byte anterior 
-          INC   HL                ; +          inc hl 
-          LD   E,A                ; recuperar el ultimo byte leido +          ld ea                        ; recuperar el ultimo byte leido 
-          JR   byte_2             ; continuar con la compresion +          jr byte_2                      ; continuar con la compresion 
-ultimo_byte   LD   [HL],E         ; escribir el ultimo byte +rle_ultimo_byte: 
-          INC   HL                ; +          ld (hl)e                     ; escribir el ultimo byte 
-          RET         ; salir +          inc hl 
-RLE_compress2 +          ret                            ; salir 
-          LD   D,#C1              ; eran identicos, empezar, con 2 +rle_compress2: 
-          JR   RLE_Repetido +          ld d$c1                      ; eran identicos,  empezar,  con 2 
-RLE_compress +          jr rle_repetido 
-          LD   D,#C0              ; era un valor RLE original +rle_compress: 
-RLE_Repetido +          ld d$c0                      ; era un valor RLE original 
-          CALL   get_byte         ; Obtener otro byte +rle_repetido: 
-          JR   Z,RLE_distinto     ; Escribir el valor RLE si no hya mas bytes +          call get_byte                  ; Obtener otro byte 
-          CP   A,E                ; Comprobar si es identico +          jr zrle_distinto             ; Escribir el valor RLE si no hya mas bytes 
-          JR   NZ,RLE_distinto    ; Se encontro un byte distinto +          cp a, E                        ; Comprobar si es identico 
-          INC                   ; incrementar el contador de repeticiones +          jr nzrle_distinto            ; Se encontro un byte distinto 
-          JR   NZ,RLE_Repetido    ; Otro byte identico +          inc d                          ; incrementar el contador de repeticiones 
-          DEC                   ; Se acabo el contador de repeticiones +          jr nzrle_repetido            ; Otro byte identico 
-RLE_distinto +          dec d                          ; Se acabo el contador de repeticiones 
-          LD   [HL],D             ; \ +rle_distinto: 
-          INC   HL                ;  \  +          ld (hl)d                     ; \ 
-byte_simple                       ;   / escribir valor RLE +          inc l                          ;  \  
-          LD   [HL],E             ;  / +rle_byte_simple:                         ;   / escribir valor RLE 
-          INC   HL                ; / +          ld (hl)e                     ;  / 
-          LD   E,A                ; Recuperar el ultimo byte distinto +          inc hl                         ; / 
-          JR   byte_2             ; seguir comprimiendo +          ld ea                        ; Recuperar el ultimo byte distinto 
-get_byte +          jr rle_byte_2                      ; seguir comprimiendo 
-          LD   A,B                ; \ +rle_get_byte: 
-          OR   A,C                ;  Comprobar si es el ultimo byte +          ld ab                        ; \ 
-          RET                   ; / +          or a, C                        ;  Comprobar si es el ultimo byte 
-          DEC   BC                ; descontar contador +          ret z                          ; / 
-          LD   A,[IX+#00]         ; leer byte +          dec bc                         ; descontar contador 
-          INC   IX                ; incrementar posicion +          ld a(ix+$00)                 ; leer byte 
-          RET+          inc ix                         ; incrementar posicion 
 +          ret
 </code> </code>
  
Línea 846: Línea 805:
  
 <code z80> <code z80>
-    LD    HL, scr_datos_zx0    ; origen = datos comprimidos +    ld    hl, scr_datos_zx0    ; origen = datos comprimidos 
-    LD    DE, 16384            ; destino = pantalla +    ld    de, 16384            ; destino = pantalla 
-    CALL  decompress_zx0+    call  decompress_zx0
 </code> </code>
  
Línea 865: Línea 824:
     ORG 33500     ORG 33500
  
-    LD HL, pantalla_comprimida   ; datos comprimidos +    ld hl, pantalla_comprimida   ; datos comprimidos 
-    LD DE, 16384                 ; destino compresion +    ld de, 16384                 ; destino compresion 
-    CALL dzx0_standard           ; descomprimir+    call dzx0_standard           ; descomprimir
  
 loop: loop:
-    JR loop                      ; bucle para no volver a BASIC+    jr loop                      ; bucle para no volver a BASIC
  
     INCLUDE "dzx0_standard.asm"     INCLUDE "dzx0_standard.asm"
Línea 929: Línea 888:
 \\  \\ 
 **[ [[.:indice|⬉]] | [[.:gfx5_mapeados|⬅]] | [[.:avanzadas1|➡]] ]** **[ [[.:indice|⬉]] | [[.:gfx5_mapeados|⬅]] | [[.:avanzadas1|➡]] ]**
 +
  • cursos/ensamblador/compresion_rle.1705571683.txt.gz
  • Última modificación: 18-01-2024 09:54
  • por sromero