Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
cursos:ensamblador:compresion_rle [10-01-2024 09:04] – [Rutina descompresora] sromero | cursos:ensamblador:compresion_rle [19-01-2024 12:35] (actual) – [Programa de ejemplo de descompresión] sromero | ||
---|---|---|---|
Línea 298: | Línea 298: | ||
<code c> | <code c> | ||
// | // | ||
- | void RLE_decompress_C( unsigned char *src, unsigned char *dst, int length ) | + | void RLE_decompress_C(unsigned char *src, unsigned char *dst, int length) |
{ | { | ||
int i; | int i; | ||
unsigned char b1, b2, j; | unsigned char b1, b2, j; | ||
- | for( i=0; i< | + | for (i=0; i< |
{ | { | ||
b1 = *src++; | b1 = *src++; | ||
- | if( b1 > 192 ) // byte comprimido? | + | if (b1 > 192) |
{ | { | ||
b2 = *src++; | b2 = *src++; | ||
i++; | i++; | ||
- | for( j=0; j<(b1 & 63); j++ ) | + | for (j=0; j<(b1 & 63); j++) { |
*dst++ = b2; | *dst++ = b2; | ||
+ | } | ||
} | } | ||
- | else | + | |
*dst++ = b1; // no, es un byte de dato (escribe) | *dst++ = b1; // no, es un byte de dato (escribe) | ||
+ | | ||
} | } | ||
} | } | ||
Línea 343: | Línea 345: | ||
RLE_decompress: | RLE_decompress: | ||
- | RLE_dec_loop: | + | rle_dec_loop: |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | RLE_dec_loop2: | + | rle_dec_loop2: |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | RLE_dec_compressed: ; bucle para descompresión | + | rle_dec_compressed: |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | RLE_dec_loop3: | + | rle_dec_loop3: |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | ; RLE no correctos. Cuidado (mem-smashing). | + | ; RLE no son correctos. Cuidado (mem-smashing). |
- | | + | |
- | | + | |
- | | + | |
</ | </ | ||
Línea 510: | Línea 512: | ||
Lo normal durante el desarrollo del juego será " | Lo normal durante el desarrollo del juego será " | ||
- | En la sección de //Ficheros y Enlaces// tenéis disponible el compresor y descompresor | + | En la sección de //Ficheros y Enlaces// tenéis disponible el compresor y descompresor |
Línea 565: | Línea 567: | ||
\\ | \\ | ||
- | * **Método INCBIN**: Incluyendo el binario directamente en PASMO con la directiva | + | * **Método INCBIN**: Incluyendo el binario directamente en Pasmo con la directiva |
Datos_Comprimidos: | Datos_Comprimidos: | ||
| | ||
Línea 571: | Línea 573: | ||
\\ | \\ | ||
- | * **Método BIN2CODE**: Convirtiendo los datos binarios a " | + | * **Método BIN2CODE**: Convirtiendo los datos binarios a " |
[sromero@compiler: | [sromero@compiler: | ||
BIN2CODE v1.0 By NoP of Compiler SoftWare | BIN2CODE v1.0 By NoP of Compiler SoftWare | ||
Línea 579: | Línea 581: | ||
[sromero@compiler: | [sromero@compiler: | ||
- | ; File created with BIN2CODE | + | ; File created with BIN2CODE |
BINDATASIZE | BINDATASIZE | ||
Línea 593: | Línea 595: | ||
</ | </ | ||
- | Es decir: el método 1 hace que PASMO incluya el binario directamente dentro de nuestro programa, y el método 2 lo convierte a directivas de datos "DB" | + | Es decir: el método 1 hace que Pasmo incluya el binario directamente dentro de nuestro programa, y el método 2 lo convierte a directivas de datos '' |
\\ | \\ | ||
Línea 601: | Línea 603: | ||
| | ||
- | El programa siguiente, | + | El programa siguiente, |
<code asm> | <code asm> | ||
; Prueba de descompresion RLE | ; Prueba de descompresion RLE | ||
; Desempaquetamos un SCR comprimido con RLE sobre la pantalla | ; Desempaquetamos un SCR comprimido con RLE sobre la pantalla | ||
- | ORG 35000 | + | |
; Cargamos los datos y preparamos nuestra rutina | ; Cargamos los datos y preparamos nuestra rutina | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
Wait_For_Keys_Pressed: | Wait_For_Keys_Pressed: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | ;; | + | ; Aquí incluiremos el código |
- | ;; RLE_decompress | + | ;; --- RLE_decompress --- |
- | ;; Descomprime un bloque | + | |
- | ;; | + | |
- | ;; 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 | + | |
- | 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: | + | |
- | 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), | + | |
- | 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. | ||
Pantalla_Comprimida: | Pantalla_Comprimida: | ||
- | | + | |
- | END 35000 | + | |
</ | </ | ||
\\ | \\ | ||
- | | + | |
Línea 690: | 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, |
\\ | \\ | ||
- | //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 '' |
\\ | \\ | ||
Línea 706: | Línea 664: | ||
;; BC = tamaño de los datos a comprimir. | ;; BC = tamaño de los datos a comprimir. | ||
;; Salida | ;; Salida | ||
- | ;; AF,DE | + | ;; AF, DE |
;; HL = HL+longitud de los datos comprimidos | ;; HL = HL+longitud de los datos comprimidos | ||
;; IX = IX+BC | ;; IX = IX+BC | ||
Línea 715: | Línea 673: | ||
;; BC = tamaño de los datos a comprimir. | ;; BC = tamaño de los datos a comprimir. | ||
;; Salida | ;; Salida | ||
- | ;; AF,DE | + | ;; AF, DE |
;; HL = HL+longitud de los datos descomprimidos | ;; HL = HL+longitud de los datos descomprimidos | ||
;; DE = DE+BC | ;; DE = DE+BC | ||
Línea 721: | Línea 679: | ||
// | // | ||
- | RLE_descompress | + | RLE_descompress: |
- | RLE_dec_loop | + | rle_dec_loop: |
- | | + | |
- | | + | |
- | | + | |
- | test_end | + | rle_test_end: |
- | | + | ldi |
- | | + | |
- | RLE_dec | + | |
- | | + | rle_dec: |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | bucle | + | |
- | | + | rle_bucle: |
- | | + | ld (de), a ; \ |
- | | + | |
- | | + | |
- | | + | |
+ | | ||
+ | | ||
// | // | ||
- | RLE_Comprimir | + | RLE_Comprimir: |
- | byte_1 | + | rle_byte_1: |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | byte_2 | + | rle_byte_2: |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | ultimo_byte | + | rle_ultimo_byte: |
- | | + | ld (hl), e ; escribir el ultimo byte |
- | | + | |
- | RLE_compress2 | + | |
- | | + | rle_compress2: |
- | | + | |
- | RLE_compress | + | |
- | | + | rle_compress: |
- | RLE_Repetido | + | |
- | | + | rle_repetido: |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | RLE_distinto | + | |
- | | + | rle_distinto: |
- | | + | |
- | byte_simple | + | |
- | | + | rle_byte_simple: |
- | | + | |
- | | + | |
- | | + | |
- | get_byte | + | |
- | | + | rle_get_byte: |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
+ | | ||
</ | </ | ||
- | |||
- | | ||
Línea 826: | Línea 785: | ||
Pasamos de 6912 bytes a sólo 1383 bytes, una reducción espectacular que nos produce un fichero sokoban.scr.zx0 listo para usar. | Pasamos de 6912 bytes a sólo 1383 bytes, una reducción espectacular que nos produce un fichero sokoban.scr.zx0 listo para usar. | ||
- | Este fichero puede ser incluído después en nuestro programa con INCBIN o introducido en un TAP para ser cargado como un bloque de datos con "LOAD "" | + | Este fichero puede ser incluído después en nuestro programa con INCBIN o introducido en un TAP para ser cargado como un bloque de datos con '' |
Después, en nuestro programa, sólo tenemos que utilizar una de las rutinas descompresoras disponibles para desempaquetar los datos comprimidos en la zona de memoria deseada. | Después, en nuestro programa, sólo tenemos que utilizar una de las rutinas descompresoras disponibles para desempaquetar los datos comprimidos en la zona de memoria deseada. | ||
Línea 846: | Línea 805: | ||
<code z80> | <code z80> | ||
- | | + | |
- | | + | |
- | | + | |
</ | </ | ||
Línea 863: | Línea 822: | ||
<code z80> | <code z80> | ||
- | ORG 33500 | + | |
- | | + | |
- | | + | |
- | | + | |
loop: | loop: | ||
- | | + | |
INCLUDE " | INCLUDE " | ||
Línea 877: | Línea 836: | ||
INCBIN " | INCBIN " | ||
- | END 33500 | + | |
</ | </ | ||
Línea 892: | Línea 851: | ||
\\ | \\ | ||
- | También tenemos disponibles en la web de ZX0 rutinas que descomprimen al revés en memoria, denominadas dzx0_standard_back y dzx0_turbo_back. | + | También tenemos disponibles en la web de ZX0 rutinas que descomprimen al revés en memoria, denominadas |
La utilidad de las rutinas " | La utilidad de las rutinas " | ||
Línea 908: | Línea 867: | ||
A día de hoy, ZX0 es una herramienta imprescindible para hacer programas y juegos de Spectrum, ya que los ratios de compresión son muy buenos y el uso de datos comprimidos (gráficos, textos, e incluso código) supone una enorme diferencia en tiempos de carga y cantidad de recursos que podemos poner en nuestros juegos. | A día de hoy, ZX0 es una herramienta imprescindible para hacer programas y juegos de Spectrum, ya que los ratios de compresión son muy buenos y el uso de datos comprimidos (gráficos, textos, e incluso código) supone una enorme diferencia en tiempos de carga y cantidad de recursos que podemos poner en nuestros juegos. | ||
- | |||
- | |||
\\ | \\ | ||
Línea 923: | Línea 880: | ||
* [[https:// | * [[https:// | ||
* {{: | * {{: | ||
- | |||
\\ | \\ | ||
Línea 929: | Línea 885: | ||
Hemos visto los fundamentos de la compresión y descompresión RLE, así como rutinas C y ASM para implementarlos en nuestros programas. Mediante lo visto en este capítulo, podemos obtener un gran ahorro de memoria en nuestros programas, pudiendo introducir más cantidad de gráficos en el mismo espacio. También permite que pueda caber más código, más sonido o más texto, ya que aunque no apliquemos la compresión sobre este tipo de datos, podremos aprovechar el espacio que dejen libre nuestros gráficos comprimidos. | Hemos visto los fundamentos de la compresión y descompresión RLE, así como rutinas C y ASM para implementarlos en nuestros programas. Mediante lo visto en este capítulo, podemos obtener un gran ahorro de memoria en nuestros programas, pudiendo introducir más cantidad de gráficos en el mismo espacio. También permite que pueda caber más código, más sonido o más texto, ya que aunque no apliquemos la compresión sobre este tipo de datos, podremos aprovechar el espacio que dejen libre nuestros gráficos comprimidos. | ||
- | |||
\\ | \\ | ||
**[ [[.: | **[ [[.: | ||
+ |