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: