Aunque programé 3 años para Commodore 64 (1988-1991), he dicho muchas veces por el foro que yo sigo prefiriendo mil veces el Z80 como procesador por su flexibilidad de registros y modos de direccionamiento. Fíjate que estos días estoy intentando apañar una rutina de descompresión de la conocida biblioteca aPLib de Joergen Ibsen, para utilizarla en Commodore 64 y me estoy volviendo loco. Literalmente. 25 años después, llevo 3 semanas y solo lo cojo a ratos perdidos, porque es frustrante adaptar un algoritmo tan complejo que apenas entiendo, a un procesador que no te deja hacer nada de nada. Y eso que parto de una rutina ya hecha para el 65C02 del Apple IIc creyendo que sería compatible con el 6502 normal... iluso de mí.
El 65C02 te deja hacer saltos relativos cortos con BRA (branch) directamente, instrucción que no existe en 6502 donde solo lo puedes hacer tras comparaciones con las banderas de acarreo (BCC, BCS), bandera de cero (BNE, BEQ), bandera de desbordamiento (BVC, BVS) y bandera de negativo (BMI, BPL). Fastidia si quieres hacer código relocalizable en 6502, porque salvo que conozcas o fuerces el valor de una bandera, acabas teniendo que programar un salto JMP absoluto y no relativo. También en 65C02 puedes poner a cero una posición de memoria sin tener que modificar antes un registro (A,X,Y) y transferirlo, e interesantes instrucciones de manipulación de bits (seteo, reseteo y consulta) sin necesitar copiar a acumulador y revisar con instrucciones lógicas (AND, OR) en forma de máscara.
Pero las cosas del 6502 que más me desquician y que sí fueron añadidas en el 65C02, que no puedo usar en el Commodore 64:
- Para 3 míseros registros de 8 bits que tienes (A,X,Y) no puedes meter X o Y en la pila, solo el acumulador A.
- Puedes incrementar y decrementar los registros índice X e Y, pero no puedes incrementar o decrementar de manera inmediata el acumulador A.
Debes hacer una suma o resta ajustando previamente la bandera de acarreo que podría estar controlando una operación anterior. No existen sumas o restas sin acarreo.
- No puedes hacer operaciones indirectas con un puntero en página cero sin depender del índice Y, que debes salvar antes (sin pila) y poner a cero para hacer el cálculo.
No me extraña que ante tanta deficiencia en ese último modo de direccionamiento indirecto, el C64, Atari u Oric acabasen plagados con código automodificable en los movimientos grandes de bloques de datos. Pongo un ejemplo de una simple instrucción para mover un byte de un lado a otro, encontrada en las rutinas de descompresión de aPLib para otros procesadores diferentes.
Elegancia en el Z80, que aún siendo un procesador de 8 bits, tiene 10 registros de 16 bits:
Código: Seleccionar todo
LD HL,origen
LD DE,destino
...
LDI <----- ya está, una única instrucción de 2 bytes y 16 ciclos que equivale a [DE]=[HL],HL++,DE++,BC--
Elegancia absoluta también en 68000, lógico siendo un procesador de 16 bits con registros de 32 bits:
Código: Seleccionar todo
lea origen,A0
lea destino, A1
...
move.b (a0)+,(a1)+ <---- lo mismo, mueve un byte y postincrementa sin necesitar comodines intermedios
Sin embargo, la locura absoluta en 6502 por no tener registros puros de 16 bits:
Código: Seleccionar todo
LDA #origen_low <---- los 8 bits bajos de una dirección de 16 bits
STA puntero_origen
LDA #origen_high <---- los 8 bits altos de una dirección de 16 bits
STA puntero_origen+1
LDA #destino_low
STA puntero_destino
LDA #destino_high
STA puntero_destino+1
...
PHA
TYA
PHA
LDY #$00
LDA (puntero_origen),Y
STA (puntero_destino),Y
INC puntero_origen
BNE +
INC puntero_origen+1
+ INC puntero_destino
BNE ++
INC puntero_destino+1
++ PLA
TAY
PLA
Por eso a la gente que programa en 6502 como nuestro compañero Explorer en el Atari o Chema en el Oric (que por cierto, tiene mañana una Bola Extra sobre Oric en el programa Amiga Wave en YouTube), es para quitarse el sombrero... yo nunca tuve la paciencia de hacer cosas complejas en C64, y eso que crackeaba, ripeaba músicas y hacía intros con scroll y logos moviéndose. Será que era más joven.