Ayuda para destripar/ripear un ejecutable de C64.

BlackHole
Mensajes: 1131
Registrado: 03 Ago 2011 23:07
Ubicación: Aluche, Madrid
Agradecido : 11 veces
Agradecimiento recibido: 251 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor BlackHole » 28 Ago 2019 13:46

Último mensaje de la página anterior:

minter: Ten en cuenta que todo el proceso de la versión de aPLib por ahora es completamente manual, y soy yo quien mueve el programa al final de la memoria porque la rutina descomprime hacia adelante. En el caso específico del Aliens, el emulador VICE 3.1 me está dando 344.148 ciclos para mover los datos y 3.242.907 ciclos para descomprimirlo. Tengo pendiente desde hace 1 año programar una versión de la rutina 6502 que descomprima hacia atrás (en teoría sería sencillo, solo habría que decrementar y restar donde está incrementando y sumando ahora, pero lo he ido dejando por pura vagancia).

En Z80 sí lo hice en su día, y los resultados son exactamente los mismos ciclos de procesador. Le cuesta exactamente lo mismo incrementar que decrementar. Así que en teoría solo te ahorrarías el tiempo de mover los datos. Lo que sí cambia es el resultado de la compresión, es diferente si se comprime en un sentido que en otro. El programa que tengo hecho desde hace 15 años para gestionar la librería de aPLib, me comprime 2 veces: al derecho y al revés, y uso uno u otro resultado según me convenga. A veces se ahorra un puñado de bytes, pero en el caso del Aliens era al contrario: ¡eran 98 bytes mas!

sharklodon
Mensajes: 14
Registrado: 29 Ago 2019 08:55
Agradecido : 3 veces
Agradecimiento recibido: 3 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor sharklodon » 29 Ago 2019 14:43

Hola,
Una duda sobre el exomizer, todos eso parametros que añades, no creo que sean estandar para todos los prg, no? Como los sacas?

Gracias,

Avatar de Usuario
kikems
Mensajes: 3423
Registrado: 30 May 2013 19:23
Agradecido : 1001 veces
Agradecimiento recibido: 1369 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor kikems » 29 Ago 2019 16:14

BlackHole escribió:minter: Ten en cuenta que todo el proceso de la versión de aPLib ....


Creo que aquí todos queremos ser tus Padawan. -thumbup

BlackHole
Mensajes: 1131
Registrado: 03 Ago 2011 23:07
Ubicación: Aluche, Madrid
Agradecido : 11 veces
Agradecimiento recibido: 251 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor BlackHole » 29 Ago 2019 20:20

Una duda sobre el exomizer, todos eso parametros que añades, no creo que sean estandar para todos los prg, no? Como los sacas?

Contestación rápida porque estoy en la calle con el móvil. El parámetro $8009 es la dirección de arranque del juego Aliens (otros juegos tendrán otra). El fichero 0800-FFF7.prg es obviamente lo que estaba comprimiendo: el volcado de memoria que hice con VICE.

El resto pueden usarse en cualquier programa. Las instrucciones están en el ZIP del Exomizer, tanto las del 2.0 como las extendidas del 3.0.

El comando -n desactiva los efectos en pantalla, ahorra tiempo en la descompresión. El comando -M 256 como expliqué restringe la búsqueda de patrones a 256 bytes, haciendo que comprima menos (a veces bastante menos) pero acelerando la velocidad de descompresión. El objetivo no era crear el "mejor" ejecutable, sino comparar las velocidades con aPLib. El comando -s permite añadir instrucciones ASM que se ejecutan antes de empezar a descomprimir, en este caso, desactivando la pantalla y poniendo el borde negro. Hay un equivalente -f que permite añadir instrucciones tras acabar la descompresión; como el propio juego inicializa por sí mismo de nuevo la pantalla, no necesité usarlo.

Porque este nuevo Exomizer 3.0.x es bastante más rápido. En el anterior podría tardar perfectamente 8-10 segundos, y para que no pareciese que se había colgado, a mí me gustaba usar el comando -X "inc $d020 dec $d020" para que saliese una rayita de color por pantalla cada 256 bytes descomprimidos. Así no ralentizaba demasiado el proceso (4 veces por KB) y daba cierto feedback al usuario. Ahora no veo que haga falta.

sharklodon
Mensajes: 14
Registrado: 29 Ago 2019 08:55
Agradecido : 3 veces
Agradecimiento recibido: 3 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor sharklodon » 30 Ago 2019 10:42

Hola,
Muchas gracias por tu aclaración, pero aun tengo la duda de saber como se saca la dirección de arranque de cada juego. ¿Me podías indicar como hacerlo?

Muchas gracias,

BlackHole
Mensajes: 1131
Registrado: 03 Ago 2011 23:07
Ubicación: Aluche, Madrid
Agradecido : 11 veces
Agradecimiento recibido: 251 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor BlackHole » 30 Ago 2019 11:28

Pues eso estará en el cargador de cinta o disco usado para cargar el juego en memoria.
Iba a añadir "obviamente", pero por tu pregunta veo que puede no ser tan obvio.

sharklodon
Mensajes: 14
Registrado: 29 Ago 2019 08:55
Agradecido : 3 veces
Agradecimiento recibido: 3 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor sharklodon » 30 Ago 2019 21:04

Hola,
Lo siento, te vuelvo a molestar, pero sigo sin entender cómo podemos conseguir ese valor. O quizás debería preguntártelo de otra forma, ¿que diferencia hay en poner sfx basic a sfx $8009?
Gracias de nuevo.

BlackHole
Mensajes: 1131
Registrado: 03 Ago 2011 23:07
Ubicación: Aluche, Madrid
Agradecido : 11 veces
Agradecimiento recibido: 251 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor BlackHole » 31 Ago 2019 00:14

¿Conseguir el valor? Desensamblando como si estuviésemos crackeando el juego. La diferencia es que "sfx basic" necesita que exista una orden SYS al inicio del BASIC, algo que en los originales no existe nunca (salvo quizás alguno de 1982/1983).

sharklodon
Mensajes: 14
Registrado: 29 Ago 2019 08:55
Agradecido : 3 veces
Agradecimiento recibido: 3 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor sharklodon » 31 Ago 2019 10:26

Veo que se me escapa, y tampoco es necesario. Gracias por tu ayuda.

sharklodon
Mensajes: 14
Registrado: 29 Ago 2019 08:55
Agradecido : 3 veces
Agradecimiento recibido: 3 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor sharklodon » 22 Sep 2019 20:42

Hola,
Ataco de nuevo, y si no es molestia, ¿ nos podrías explicar como haces el volcado de memoria desde el VICE ?
Muchas gracias,

BlackHole
Mensajes: 1131
Registrado: 03 Ago 2011 23:07
Ubicación: Aluche, Madrid
Agradecido : 11 veces
Agradecimiento recibido: 251 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor BlackHole » 23 Sep 2019 00:43

No tiene misterio, desde el Monitor, con el comando bs (binary save) "nombre fichero" unidad (0 para PC) direccion inicio dirección fin

Código: Seleccionar todo

Syntax: bsave "<filename>" <device> <address1> <address2>
Abbreviation: bs

Save the memory from address1 to address2 to the specified file.
If device is 0, the file is written to the file system.

BlackHole
Mensajes: 1131
Registrado: 03 Ago 2011 23:07
Ubicación: Aluche, Madrid
Agradecido : 11 veces
Agradecimiento recibido: 251 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor BlackHole » 04 Oct 2019 13:32

minter escribió:El Exomizer Coloca el bloque comprimido al principio de la memoria y empieza a descomprimir desde el final hasta el principio.
Mientras que el de Antonio lo hace del revés. Carga el bloque comprimido al final de la memoria y va descomprimiendo desde el principio al final.
Debe de estar esa ganancia de velocidad relacionada con el contador del programa y no con el método de compresión.
Le debe resultar mas rápido al ordenador volver a situarse al principio para dejar la memoria descomprimida, que leer al principio y ir escribiendo en el final.

Complejidad para el uso de punteros de 16 bits en procesador 6502

Es sabido que el 6502 (o sus variantes 6510/7501/8500/8501/8502) es un procesador de 8 bits con solo 3 registros de 8 bits (A,X,Y) con los que tienes que hacer malabarismos apoyados en memoria, para hacer cualquier cálculo matemático serio. Por lo tanto debes usar 2 direcciones de memoria seguidas que almacenen el byte bajo y el byte alto del puntero de 16 bits; en el 6502 esto se debe se hace en página cero (los primeros 256 bytes de RAM) porque el juego de instrucciones incorpora un modo de direccionamiento especial para usar esa zona de memoria ahorrandote ciclos, pero las capacidades son muy limitadas pues el 6502 no es apenas ortogonal. Algunas de estas limitaciones se mejoraron en el 65C02 (Apple IIc, Acorn BBC Master, Atari Lynx) y en el 65C816 (Apple IIGS, Super Nintendo). Pero bueno, ya hablé de ello en mi hilo Z80 vs 6502/6510 vs 65C02.

Por lo tanto, si queremos traducir la instrucción en lenguaje C: *destino++ = *origen++ para copiar un byte de memoria y postincrementar los punteros, algo que en Z80 se haría con una simple instrucción LDI pues en 6502 tenemos que armar todo un cristo, encima asegurandonos todo el rato que Y sea cero, porque el C64 no tiene direccionamiento indirecto sin depender de Y:

	LDA	(ptr_origen),Y
INC ptr_origen ; Byte bajo
BNE +
INC ptr_origen+1 ; Byte alto
+ STA (ptr_destino),Y
INC ptr_destino ; Byte bajo
BNE ++
INC prt_destino+1 ; Byte alto
++ ...

Si queremos realizar la rutina inversa, que vaya descomprimiendo al revés, lo que vendría a ser *destino-- = *origen-- postdecrementando los punteros, que en Z80 se haría con LDD, pues en 6502 se complica en demasía debido a que la bandera de cero (Z) solo se activa cuando el resultado es cero, y cuando llegamos a una dirección $XX00, todavía debemos copiar ese byte antes de pasar a la página inferior $YYFF, siendo Y=X-1 ... no sé si me explico bien. Tampoco podemos usar la bandera de negativo (N) porque ésta estaría activa para todos los casos entre $80 y $FF. Por lo tanto debemos comprobar antes el valor del byte y usar la función de resta en vez de la función de decrementado, con lo que perdemos demasiados ciclos de reloj (tiempo de CPU).

	LDA	(ptr_origen),Y
TAX ; Guardamos valor obtenido porque las restas necesitan el acumulador
SEC
LDA ptr_origen ; Byte bajo
SBC #1
STA ptr_origen ; Byte bajo
BCC +
DEC ptr_origen+1 ; Byte alto
+ TXA ; Recuperamos el valor. No existe la instrucción STX (NN),Y
STA (ptr_destino),Y
SEC
LDA ptr_destino ; Byte bajo
SBC #1
STA ptr_destino ; Byte bajo
BCC ++
DEC ptr_destino+1 ; Byte alto
++ ...

Exomizer lo que hace es jugar con el registro Y, hacerlo variar entre 0 y 255, para sumarlo al puntero. Pero implica una rutina diferente que no use Y para otras cosas a lo largo de su código de descompresión. No sé si esta rutina se podría optimizar... le ando dando vueltas, pero veo mala solución.

Avatar de Usuario
explorer
Mensajes: 326
Registrado: 10 Ene 2016 18:43
Ubicación: Valladolid, España
Agradecido : 7 veces
Agradecimiento recibido: 293 veces
Contactar:

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor explorer » 04 Oct 2019 22:29

Lo ideal es no tener que actualizar los punteros en cada vuelta del bucle, sino usar X o Y (en caso de direccionamiento indexado) o Y (en caso de dir. ind. de pág. cero) para recorrer 256 posiciones, y así solo tienes que decrementar los bytes altos de los punteros para "pasar" a la página siguiente.

El truco está en empezar con el valor de índice igual a 0 para que realice la copia del byte apuntado al principio por el puntero origen.

Con esto, te evitas aritmética de 16 bits (decrementar los bytes altos se supone que nunca salen del rango de los 64 KiB) y solo usas un registro índice, dejando el otro para contador de páginas a copiar, si es necesario.

(Quizás esto es lo que hace exomizer, no lo sé).

Aquí un ejemplo que se puede ejecutar en http://skilldrick.github.io/easy6502/#first-program o en http://www.6502asm.com/

; -- copia inversa de 3 páginas, en orden inversa

ldx #$04 ; pintar pantalla (para tener algo que mover)
ldy #$00

lda #$00
sta $20
lda #$02
sta $21

fill:
lda $fe
sta ($20),y
iny
bne fill
inc $21
dex
bne fill

;-- Copia de origen a destino, X páginas, hacia atrás

lda #$FF ; puntero origen
sta $10
lda #$05
sta $11

lda #$FF ; puntero destino
sta $20
lda #$04
sta $21


ldx #$04 ; número de páginas a copiar +1
ldy #$00 ; para copiar el primer byte

loop:
lda ($10),y ; leer dato
sta ($20),y ; escribir dato

dey ; siguiente dato
cpy #$FF ; ¿fin de página?
bne loop ; no, repetir

dec $11 ; apuntamos a las páginas anteriores
dec $21

dex ; una página menos
bne loop


Para una rutina de descompresión, pues bastaría con tener una copia del índice Y en una posición de la RAM, en la página cero, claro. Al principio del procedimiento lo recuperamos y al final lo guardamos para la siguiente vuelta.

(no probado)
; -- copia de 1 byte, y decremento de punteros, en orden inverso
; -- inicializar (10,11) con el puntero origen, (20,21) con el destino, y (12) con 0

copia1:
ldy $12 ; valor actual del índice

lda ($10),y ; leer dato
sta ($20),y ; escribir dato

dey ; siguiente dato
cpy #$FF ; ¿fin de página?
bne fin_copia1 ; no, salir

dec $11 ; apuntamos a las páginas anteriores
dec $21

fin_copia1:
sty $12
rts

Aún nos sobraría el registro X para, por ejemplo, copiar más de un byte (no probado):

; -- copia de X bytes, y decremento de punteros, en orden inverso
; -- inicializar (10,11) con el puntero origen, (20,21) con el destino, y (12) con 0

copia1:
ldy $12 ; valor actual del índice

loop_copia1:
lda ($10),y ; leer dato
sta ($20),y ; escribir dato

dey ; siguiente dato
cpy #$FF ; ¿fin de página?
bne fin_copia1 ; no, salir

dec $11 ; apuntamos a las páginas anteriores
dec $21

fin_copia1:
dex
bne loop_copia1

sty $12
rts

BlackHole
Mensajes: 1131
Registrado: 03 Ago 2011 23:07
Ubicación: Aluche, Madrid
Agradecido : 11 veces
Agradecimiento recibido: 251 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor BlackHole » 05 Oct 2019 02:45

El procedimiento de lectura y escritura de un solo byte solo era un ejemplo reducido del problema. La copia de un byte es solo 1 caso de 5. La rutina de descompresión evalúa patrones de bits (almacenados en Gamma Code) que codifican un tipo diferente de patrón de repetición de datos: copia de un bloque largo ya descomprimido, para lo que tenemos que calcular un nueva dirección de origen provisional restando el desplazamiento (sumando si fuésemos al revés), copia de un numero corto de bytes ya descomprimidos en otro tipo de desplazamientos cortos cuya longitud cabe en 1 byte, copia de 1 byte nuevo del flujo de entrada...

En fin, algoritmo bastante complejo que si he de ser sincero NO comprendo al 100% todavía. Gracias a que está completada la rutina que descomprime hacia adelante... porque la que va hacia atrás no la visualizo en código del 6502. De lo que me quejaba es que en Z80 y 68000 eran ordenes rápidas e inmediatas al incorporar aritmética de 16 bits, que al incrementar tenían el mismo número de ciclos que al decrementar posibilitando ambas rutinas. En 6502 parece imposible sin rehacer todo. Mi primera prueba de compilación me falla porque me salen saltos relativos mayores de 128 bytes: la rutina desenrollada es demasiado larga... y si se enrolla usando JSR/RET pues no merece la pena por los tiempos perdidos en las llamadas.

Será mejor que me dedique a la cría de caracoles.

Avatar de Usuario
explorer
Mensajes: 326
Registrado: 10 Ene 2016 18:43
Ubicación: Valladolid, España
Agradecido : 7 veces
Agradecimiento recibido: 293 veces
Contactar:

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor explorer » 05 Oct 2019 23:42

Es lo malo de estos algoritmos tan optimizados: no sabemos cómo lo hacen sin hacer un desensamblado y puesta de comentarios "al vuelo" a ver si "acertamos". Como nos falta la explicación teórica -y los comentarios originales- pues se convierte en un infierno.

Otras veces son algoritmos "conocidos", quizás un Lempel–Ziv–Welch, pero al personalizarse para el 6502, y descomprimirse de adelante-atrás... pues otro follón de entender.

Esto es arqueología informática en estado puro.

P.D.: el precio del caracol, en lonja, julio 2017, estaba a 3.5 €/kilo. ;-)

BlackHole
Mensajes: 1131
Registrado: 03 Ago 2011 23:07
Ubicación: Aluche, Madrid
Agradecido : 11 veces
Agradecimiento recibido: 251 veces

Re: Ayuda para destripar/ripear un ejecutable de C64.

Mensajepor BlackHole » 06 Oct 2019 02:40

No entiendo lo que quieres decir con "puesta de comentarios al vuelo a ver si acertamos".


Volver a “Software C64”

¿Quién está conectado?

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