Ejemplos con aPLib para C64

PET, VIC-20, MAX Machine, 64, 64x, SX-64, 16, Plus/4, 128, 65 ...
BlackHole
Amiga 1200
Amiga 1200
Mensajes: 1043
Registrado: 07 Nov 2009, 11:38
Ubicación: Madrid
Gracias dadas: 2 veces
Gracias recibidas: 67 veces

Ejemplos con aPLib para C64

Mensajepor BlackHole » 18 Oct 2017, 19:45

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:
Hunter's Moon [BH][2017].d64.gz
Hunter's Moon C64
(34.9 KiB) Descargado 8 veces
Última edición por BlackHole el 20 Oct 2017, 16:47, editado 2 veces en total.

garillete
Amiga 2500
Amiga 2500
Mensajes: 2637
Registrado: 08 May 2006, 19:31
Gracias dadas: 3 veces
Gracias recibidas: 9 veces

Re: aPLib para C64. Hunter's Moon 30 aniversario.

Mensajepor garillete » 18 Oct 2017, 20:36

Pues lo primero felicidades... me admira la gente que es capaz de progamar utilidades, herramientas, juegos...
Antiguos Bytes.
http://zonadepruebas.org/garillete

Avatar de Usuario
antoniovillena
Amiga 1200
Amiga 1200
Mensajes: 2004
Registrado: 16 Abr 2012, 21:22
Gracias recibidas: 3 veces

Re: aPLib para C64. Hunter's Moon 30 aniversario.

Mensajepor antoniovillena » 18 Oct 2017, 22:47

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.

BlackHole
Amiga 1200
Amiga 1200
Mensajes: 1043
Registrado: 07 Nov 2009, 11:38
Ubicación: Madrid
Gracias dadas: 2 veces
Gracias recibidas: 67 veces

Ejemplos con aPLib para C64: código fuente

Mensajepor BlackHole » 20 Oct 2017, 13:41

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.

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.

Avatar de Usuario
marcos64
Amiga 1200
Amiga 1200
Mensajes: 1193
Registrado: 03 Sep 2011, 07:53
Gracias dadas: 5 veces
Gracias recibidas: 14 veces

Re: aPLib para C64. Hunter's Moon 30 aniversario.

Mensajepor marcos64 » 20 Oct 2017, 15:18

Lo del 60% mas rapida que Exomizer es impresionante :!:

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.

BlackHole
Amiga 1200
Amiga 1200
Mensajes: 1043
Registrado: 07 Nov 2009, 11:38
Ubicación: Madrid
Gracias dadas: 2 veces
Gracias recibidas: 67 veces

Ejemplos con aPLib para C64

Mensajepor BlackHole » 20 Oct 2017, 16:37

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. :mrgreen:

Avatar de Usuario
antoniovillena
Amiga 1200
Amiga 1200
Mensajes: 2004
Registrado: 16 Abr 2012, 21:22
Gracias recibidas: 3 veces

Re: Ejemplos con aPLib para C64: código fuente

Mensajepor antoniovillena » 21 Oct 2017, 05:16

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.

BlackHole
Amiga 1200
Amiga 1200
Mensajes: 1043
Registrado: 07 Nov 2009, 11:38
Ubicación: Madrid
Gracias dadas: 2 veces
Gracias recibidas: 67 veces

Re: Ejemplos con aPLib para C64

Mensajepor BlackHole » 21 Oct 2017, 12:10

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".

Avatar de Usuario
antoniovillena
Amiga 1200
Amiga 1200
Mensajes: 2004
Registrado: 16 Abr 2012, 21:22
Gracias recibidas: 3 veces

Re: Ejemplos con aPLib para C64

Mensajepor antoniovillena » 21 Oct 2017, 13:03

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

Avatar de Usuario
marcos64
Amiga 1200
Amiga 1200
Mensajes: 1193
Registrado: 03 Sep 2011, 07:53
Gracias dadas: 5 veces
Gracias recibidas: 14 veces

Re: Ejemplos con aPLib para C64

Mensajepor marcos64 » 21 Oct 2017, 16:10

BlackHole escribió:Solo voy a convertir algunos juegos en cinta que me gustaron de joven, ya estoy muy mayor para buscar otro reconocimiento. :mrgreen:


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.


Volver a “Commodore”

¿Quién está conectado?

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