Hola a todos.
Ayer fue mi cumpleaños y quería obsequiaros con un pequeño trabajo que he estado haciendo durante los últimos días. Se trata de un ejemplo real de una implementación en 6502 de una rutina de descompresión de aPLib optimizada para velocidad. Está basada en un código anterior del micro 65C02 para Apple IIc, que como algunos sabréis, posee más instrucciones y modos de direccionamiento que permiten ahorrar bytes, así que la conversión ha sido complicada... como tiene muchos bucles desenrollados y el código de 6502 ya de por sí ocupa mucho más que el de Z80, al final la rutina ha quedado en 327 bytes. Es un 60% más rápida que Exomizer y los datos comprimidos apenas (en este caso) son un 1.5% más largos.
He escogido el juego Hunter's Moon de Thalamus, que cumple 30 años. La versión incluye la pantalla y música de carga de la cinta, el juego "descongelado" ya que el máster está realizado con el Expert Cartridge 2.9, y arreglado un pequeño "glitch" gráfico que tiene el original al comienzo del juego:
Juegos C64 comprimidos
-
- Amiga 1200
- Mensajes: 1442
- Registrado: 07 Nov 2009, 11:38
- Sistema Favorito: C64
- primer_sistema: Spectrum 16Kb/48Kb
- consola_favorita: Nintendo SNES
- Primera consola: Nintendo SNES
- Ubicación: Madrid
- Gracias dadas: 9 veces
- Gracias recibidas: 209 veces
Juegos C64 comprimidos
Última edición por BlackHole el 24 Dic 2022, 20:52, editado 9 veces en total.
-
- Amiga 2500
- Mensajes: 3250
- Registrado: 08 May 2006, 19:31
- Gracias dadas: 240 veces
- Gracias recibidas: 421 veces
Re: aPLib para C64. Hunter's Moon 30 aniversario.
Pues lo primero felicidades... me admira la gente que es capaz de progamar utilidades, herramientas, juegos...
Antiguos Bytes.
http://zonadepruebas.org/garillete
http://zonadepruebas.org/garillete
- antoniovillena
- Amiga 1200
- Mensajes: 2013
- Registrado: 16 Abr 2012, 21:22
- Gracias recibidas: 8 veces
Re: aPLib para C64. Hunter's Moon 30 aniversario.
Primero felicidades, aunque sea con retraso. Segundo, ¿no vas a publicar el código fuente? Te lo digo porque alguien podría desensamblarlo y atribuirse los créditos.
-
- Amiga 1200
- Mensajes: 1442
- Registrado: 07 Nov 2009, 11:38
- Sistema Favorito: C64
- primer_sistema: Spectrum 16Kb/48Kb
- consola_favorita: Nintendo SNES
- Primera consola: Nintendo SNES
- Ubicación: Madrid
- Gracias dadas: 9 veces
- Gracias recibidas: 209 veces
Ejemplos con aPLib para C64: código fuente
Hola Antonio,
Quería haber pegado la rutina tanto aquí como en RW simultaneamente, porque en el otro foro sé que paran un par de gurús del 6502 (Silicebit, Chema) del mundo Oric y quería que echasen un vistazo por si podían optimizarla... pero como estoy teniendo problemas allí para adjuntar archivos, la dejo aquí por ahora.
Como dije más arriba, está basada en un código anterior de 65C02 que es más corto. Es un procesador que tiene direccionamiento indirecto puro, no como el 6502 que únicamente tiene indirecto indexado (que además gasta un ciclo de reloj más) y eso te obliga a inicializar el registro Y a cero y mantenerlo así todo el rato, con el coste en bytes que supone. Otras características del 65C02 que no puedo usar, son el mover a pila el registro X y el registro Y directamente sin pasar por el acumulador.
Esta rutina es la versión 15 y por más vueltas que le doy no consigo optimizarla más. Cualquier sugerencia será bienvenida.
Es complicado, ya que el procesador no tiene ningún registro de 16 bits ni tampoco instrucciones para cálculos aritméticos de 16 bits, con lo que las operaciones a 8 bits se llevan gran parte del código, y por consiguiente del tiempo de proceso. El que el reloj del 6510 en el Commodore 64 PAL sea de 985 kHz (ni siquiera 1 MHz), ya termina de matar al micro.
Quería haber pegado la rutina tanto aquí como en RW simultaneamente, porque en el otro foro sé que paran un par de gurús del 6502 (Silicebit, Chema) del mundo Oric y quería que echasen un vistazo por si podían optimizarla... pero como estoy teniendo problemas allí para adjuntar archivos, la dejo aquí por ahora.
Como dije más arriba, está basada en un código anterior de 65C02 que es más corto. Es un procesador que tiene direccionamiento indirecto puro, no como el 6502 que únicamente tiene indirecto indexado (que además gasta un ciclo de reloj más) y eso te obliga a inicializar el registro Y a cero y mantenerlo así todo el rato, con el coste en bytes que supone. Otras características del 65C02 que no puedo usar, son el mover a pila el registro X y el registro Y directamente sin pasar por el acumulador.
Esta rutina es la versión 15 y por más vueltas que le doy no consigo optimizarla más. Cualquier sugerencia será bienvenida.
Es complicado, ya que el procesador no tiene ningún registro de 16 bits ni tampoco instrucciones para cálculos aritméticos de 16 bits, con lo que las operaciones a 8 bits se llevan gran parte del código, y por consiguiente del tiempo de proceso. El que el reloj del 6510 en el Commodore 64 PAL sea de 985 kHz (ni siquiera 1 MHz), ya termina de matar al micro.
Código: Seleccionar todo
; aPLib 6502 depacker for C64 by Francisco Crespo (Black Hole)
; Based on an earlier 65C02 depacker for Apple IIc by Peter Ferrie
; Depacker variables
.DEFINE TMPY = $A7
.DEFINE tmp = $A8 ; A8/A9
.DEFINE newsrc = $AA ; AA/AB
.DEFINE ecx = $F7 ; F7/F8
.DEFINE last = $F9 ; F9/FA
.DEFINE src = $FB ; FB/FC
.DEFINE dst = $FD ; FD/FE
.MACRO GETBIT_M
txa
asl
bne ++
lda (src),Y
inc src
bne +
inc src+1
+ rol a
++ tax
.ENDM
.MACRO GETSRC_M
LDA (src),Y
INC src
BNE +
INC src+1
+
.ENDM
.MACRO PUTDST_M
STA (dst),Y
INC dst
BNE +
INC dst+1
+
.ENDM
depack: LDX #$80
LDY #$00
STY ecx+1 ; Y=0
literal:
GETSRC_M
PUTDST_M
;ldy #2
LDA #$02
STA TMPY
nexttag:
GETBIT_M
bcc literal
GETBIT_M
bcc codepair
GETBIT_M
bcs onebyte
GETSRC_M
lsr
beq donedepacking
STY ecx ; Y=0
rol ecx
sta last
STY last+1 ; Y=0
JMP domatch_with_2inc
donedepacking:
RTS
onebyte
;ldy #1
;sty ecx
;iny
LDA #1
STA ecx
LDA #2
STA TMPY
lda #$10
getmorebits
pha
GETBIT_M
pla
rol
bcc getmorebits
STY tmp+1 ; Y=0
bne domatch
PUTDST_M
JMP nexttag
codepair
jsr getgamma
LDA ecx
SEC
SBC TMPY
STA TMPY
ora ecx+1
bne normalcodepair
jsr getgamma
JMP domatch_lastpos
normalcodepair
GETSRC_M
sta last
jsr getgamma
;dey
;sty last+1
dec TMPY
LDA TMPY
STA last+1
;cpy #$7d
CMP #$7D
bcs domatch_with_2inc
;cpy #5
CMP #$05
bcs domatch_with_inc
lda last
bmi domatch_lastpos
;tya
LDA TMPY
bne domatch_lastpos
domatch_with_2inc
inc ecx
bne domatch_with_inc
inc ecx+1
domatch_with_inc
inc ecx
bne domatch_lastpos
inc ecx+1
domatch_lastpos
;ldy #1
LDA #1
STA TMPY
lda last+1
sta tmp+1
lda last
domatch:
sta tmp
lda dst
sec
sbc tmp
sta newsrc
lda dst+1
sbc tmp+1
sta newsrc+1
lda ecx
beq dloop
- LDA (newsrc),Y
INC newsrc
BNE +
INC newsrc+1
+ PUTDST_M
dec ecx
bne -
lda ecx+1
beq +++
dloop: LDA (newsrc),Y
INC newsrc
BNE ++
INC newsrc+1
++ PUTDST_M
dec ecx
bne dloop
dec ecx+1
bne dloop
+++ JMP nexttag
getgamma:
LDA #$01
STA ecx
STY ecx+1 ; Y=0
txa ; GETBIT_1
gloop: asl a
bne ++
lda (src),Y
inc src
bne +
inc src+1
+ rol a
++ rol ecx
rol ecx+1
asl a ; GETBIT_2
bne ++
lda (src),Y
inc src
bne +
inc src+1
+ rol a
++ bcs gloop
tax ; stillbitsleft
rts
end_depack:
Última edición por BlackHole el 20 Oct 2017, 17:14, editado 2 veces en total.
- marcos64
- Amiga 1200
- Mensajes: 1376
- Registrado: 03 Sep 2011, 07:53
- Gracias dadas: 59 veces
- Gracias recibidas: 32 veces
Re: aPLib para C64. Hunter's Moon 30 aniversario.
Lo del 60% mas rapida que Exomizer es impresionante
Subela tambien a CSDb, seguro que alli encuentras quien le pueda hechar un vistazo.
Subela tambien a CSDb, seguro que alli encuentras quien le pueda hechar un vistazo.
http://marcos64.orgfree.com/
Actualizacion 11/6/2015: Añadida Load'N'Run numero 3.
Actualizacion 11/6/2015: Añadida Load'N'Run numero 3.
-
- Amiga 1200
- Mensajes: 1442
- Registrado: 07 Nov 2009, 11:38
- Sistema Favorito: C64
- primer_sistema: Spectrum 16Kb/48Kb
- consola_favorita: Nintendo SNES
- Primera consola: Nintendo SNES
- Ubicación: Madrid
- Gracias dadas: 9 veces
- Gracias recibidas: 209 veces
Ejemplos con aPLib para C64
Me acabo de enterar que justo hay un proyecto de crowdfunding para crear un juego nuevo de Hunter's Moon completamente diferente al original de 1987, así que para no confundir al personal, voy a cambiar el título y dedicar este hilo a mis futuros apaños con Commodore 64. No prentendo que mis trabajos sean equivalentes a los de grupos como Remember o Nostalgia, puesto que ni tengo intención de complicarlos con trainers ni cargadores de puntuaciones, ni pegar una intro con un logotipo delante de cada juego.
Solo voy a convertir algunos juegos en cinta que me gustaron de joven, ya estoy muy mayor para buscar otro reconocimiento.
Solo voy a convertir algunos juegos en cinta que me gustaron de joven, ya estoy muy mayor para buscar otro reconocimiento.
- antoniovillena
- Amiga 1200
- Mensajes: 2013
- Registrado: 16 Abr 2012, 21:22
- Gracias recibidas: 8 veces
Re: Ejemplos con aPLib para C64: código fuente
BlackHole escribió:Esta rutina es la versión 15 y por más vueltas que le doy no consigo optimizarla más. Cualquier sugerencia será bienvenida.
Es complicado, ya que el procesador no tiene ningún registro de 16 bits ni tampoco instrucciones para cálculos aritméticos de 16 bits, con lo que las operaciones a 8 bits se llevan gran parte del código, y por consiguiente del tiempo de proceso. El que el reloj del 6510 en el Commodore 64 PAL sea de 985 kHz (ni siquiera 1 MHz), ya termina de matar al micro.
Gracias por compartir. ¿Cómo haces para ver lo que tarda? ¿Usas algún emulador que te cuenta los ciclos? Es que me gustaría adaptar el descompresor del zx7b a 6502 pero si no tengo una herramienta que me diga exactamente lo que dura la ejecución, me va a ser muy complicado optimizar.
-
- Amiga 1200
- Mensajes: 1442
- Registrado: 07 Nov 2009, 11:38
- Sistema Favorito: C64
- primer_sistema: Spectrum 16Kb/48Kb
- consola_favorita: Nintendo SNES
- Primera consola: Nintendo SNES
- Ubicación: Madrid
- Gracias dadas: 9 veces
- Gracias recibidas: 209 veces
Re: Ejemplos con aPLib para C64
VICE lo hace automáticamente. Entras en el monitor con ALT+M, usas "sw reset" para inicializar el cronómetro (stopwatch) y en cada instrucción te muestra el contador de ciclos. Puedes poner puntos de ruptura permanentes con "break" o de un solo uso con "until".
- antoniovillena
- Amiga 1200
- Mensajes: 2013
- Registrado: 16 Abr 2012, 21:22
- Gracias recibidas: 8 veces
Re: Ejemplos con aPLib para C64
BlackHole escribió:VICE lo hace automáticamente. Entras en el monitor con ALT+M, usas "sw reset" para inicializar el cronómetro (stopwatch) y en cada instrucción te muestra el contador de ciclos. Puedes poner puntos de ruptura permanentes con "break" o de un solo uso con "until".
Muchas gracias. Pues a ver si me pongo. Me gustaría hacer un benchmark Exomizer vs Aplib vs ZX7B. También he encontrado otra implementación de Aplib para C64 (tiene pinta de ser más lenta) https://github.com/svendahl/cap/blob/ma ... k-6502.asm
- marcos64
- Amiga 1200
- Mensajes: 1376
- Registrado: 03 Sep 2011, 07:53
- Gracias dadas: 59 veces
- Gracias recibidas: 32 veces
Re: Ejemplos con aPLib para C64
BlackHole escribió:Solo voy a convertir algunos juegos en cinta que me gustaron de joven, ya estoy muy mayor para buscar otro reconocimiento.
Me atrevo a sugerir que empieces con aquellos de los que no existan cracks en condiciones. Todavia hay muchos juegos con cracks chapuceros y seguro que le das una alegria a mas de uno.
http://marcos64.orgfree.com/
Actualizacion 11/6/2015: Añadida Load'N'Run numero 3.
Actualizacion 11/6/2015: Añadida Load'N'Run numero 3.
¿Quién está conectado?
Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 12 invitados