Autor Tema: Tutorial de ensamblador de C64  (Leído 19057 veces)

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 13630
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Tutorial de ensamblador de C64
« Respuesta #15 en: Agosto 13, 2010, 08:17:43 »
Rulas, creo que tienes un "error conceptual", eso de "Ensamblador para C" no se si tiene mucho sentido :P

Ensamblador es un lenguaje y C es otro lenguaje.

En todo caso, C permite incorporar instrucciones en Ensamblador dentro de su codigo, algo asi como esos DATA para meter codigo maquina desde Basic.

A mi me esta resultando mas facil meterme con el C que con Ensamblador, ya que C es un lenguaje de uso "similar" a Basic, en cambio para Ensamblador hay que ajustar un poco mas el cerebro :D
www.retroinvaders.com | www.commodoreplus.org  | josepzin.blogspot.com

lobogris

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 453
  • Programador
    • Ver Perfil
    • http://back2theretro.blogspot.com
Tutorial de ensamblador de C64
« Respuesta #16 en: Abril 16, 2011, 16:58:54 »
bueno aunque el hilo es de hace mucho tiempo, Josezpin se quedó con la duda... y puede que alguno que esté estudiando tambien estas cosas, pueda resultarle de utilidad saber como se hacia esto.

La solución era usar punteros. Y éstos,  en código máquina 6502 (como descubrió Carlos) se hacia usando el direccionamiento indirecto con el registro Y

un pequeño ejemplo:

[code]
var  db #$00          ; var = (al valor inmediato) 0
_var equ $fa          ; _var = (a la direccion de memoria) $fa
                            ; _var será el PUNTERO de var

lda #<var              ; cargamos el byte bajo de la direccion de var
sta _var                   ; almacenamos este en el puntero _var (parte baja)
lda #>var              ; cargamos el byte alto de la direccion de var
sta _var+1             ; lo almacenamos en el puntero _var (parte alta)

lda #$07                ; cargamos el numero 7 en el reg. acumulador
ldy #$00
sta (_var),y            ; y lo almacenamos en la direccion de memoria
                             ; que apunta _var, o sea en la variable var
[/quote]

A eso que profundiceis en el uso del ensamblador en el 6502, os va a encantar usar este tipo de direccionamiento cuando os veais en la necesidad de apuntar a mas de 256 posiciones de memoria. Como por ejemplo en una rutina para borrar la pantalla (1K). Aunque hay otros métodos tambien, como código de programa automodificado ó ir copiando bloques de 256 bytes cambiando el offset de inicio en cada proceso de copia de bloque...

Silicebit

  • Commodorero
  • **
  • Mensajes: 35
    • Ver Perfil
Tutorial de ensamblador de C64
« Respuesta #17 en: Abril 16, 2011, 19:08:26 »
Ahí va una rutinilla que diseñé hace tiempo y que pertenece a mi pequeña biblioteca de rutinas en ensamblador. La presenté en un concurso de programación del C64 y creo recordar que quedó en la séptima u octava posición. Creo que está bastante bien comentada y fue escrita utilizando el MESS assembler, un paquete de programación en ensamblador que apareció publicado en el especial utilidades de Commodore World (casi pierdo las yemas de los dedos tecleándolo)  :shock: .

Se basa en lo que yo llamo DDC "definición dinámica de carácteres" y se me ocurrió para ahorrar carácteres en las animaciones, aunque seguro que ya habría algo parecido por ahí y hasta tendrá su nombre técnico y todo  :) .

¿Que qué hace? probadla y veréis. La rutina funciona por interrupciones.


[code]00000 ; ***************************
00010 ; *   RUTINA CONTADOR POR   *
00020 ; * DESLIZAMIENTO DE CIFRAS *
00030 ; *  TIPO CUENTAKILOMETROS  *
00040 ; ***************************
00050 ;
00060 ;
00070 ; ------------------------
00080 ; *** DEFINE ETIQUETAS ***
00090 ;
00100CARM .DE $3208 ;PRIMERA POSICION DEL CARACTER DECENA DE MILLAR
00110CARO .DE $30D0 ;+#$B0 APUNTA A LA PRIMERA POSICION DEL PATRON DE BITS DEL NUMERO CERO
00120CARC .DE $320F ;ULTIMA POSICION DEL CARACTER DECENA DE MILLAR
00130PVAR .DE $A8 ;PRIMERA POSICION DEL AREA DE VARIABLES
00140TEMP .DE $B1 ;VARIABLE DEL TEMPORIZADOR
00150CCAE .DE $B4 ;VARIABLE DEL NUMERO DE DESLIZAMIENTOS DEL CARACTER
00160NCON .DE $B0 ;VARIABLE DEL NUMERO DE VECES QUE HAY QUE CONTAR
00170 ; -------------------------
00180 ;
00190 .BA $1000 ; ENSAMBLAR EN $1000
00200 .OS ; ENSAMBLA EN LA MEMORIA
00210 ;
00220    PHA          ;GUARDA A EN EL STACK
00230    LDA NCON     ;COMPRUEBA SI SE DEBE INICIAR
00240    BEQ B00      ;LA CUENTA SI NO SALTA TODA LA RUTINA
00250    DEC TEMP     ;DECREMENTA TEMPORIZADOR EN UNO
00260    BNE B00      ;SI NO SE HA LLEGADO A CERO SALTA TODA LA RUTINA
00270    TYA          ;SALVA REGISTROS
00280    PHA          ;X E Y EN
00290    TXA          ;EL STACK
00300    PHA          ;
00310    LDX #$20     ;X SUMADO A CARM APUNTA PRIMERA POSICION CARACTER UNIDADES
00320B01 LDY #$07     ;CARGA Y CON NUMERO DE POSICIONES QUE COMPONEN EL CARACTER
00330B02 LDA CARM+1,X ;TOMA DATO UNA POSICION ADELANTADA+X Y
00340    STA CARM,X   ;LO ALMACENA EN POSICION ORIGINAL+X
00350    INX          ;INCREMENTA X PARA POSICION SIGUIENTE
00360    DEY          ;DECREMENTA NUMERO DE POSICIONES QUE COMPONEN EL CARACTER
00370    BNE B02      ;SALTA PARA COMPLETAR TODO EL CARACTER
00380    STX PVAR+6   ;SE GUARDA X PARA USO POSTERIOR
00390    LDX PVAR+7   ;CARGA X CON NUMERO DE CIFRA EN LA QUE SE ESTA TRABAJANDO
00400    LDY PVAR,X   ;CARGA Y CON DESPLAZAMIENTO PARA PUNTERO CARO
00410    LDA CARO,Y   ;CARGA A CON EL PATRON DE BITS DE LA CIFRA QUE DEBE APARECER POR ABAJO
00420    LDY PVAR     ;CARGA Y CON DESPLAZAMIENTO PARA PUNTERO CARC
00430    STA CARC,Y   ;ALMACENA PATRON DE BITS EN ULTIMA POSICION DEL CARACTER QUE SE TRABAJA
00440    LDY PVAR,X   ;CARGA Y CON DESPLAZAMIENTO PARA PUNTERO CARO PARA COMPARARLO DESPUES
00450    INC PVAR,X   ;INCREMENTA DESPLAZAMIENTO PARA QUE CARO APUNTE A PATRON DE BITS SIGUIENTE
00460    BNE B03      ;COMPRUEBA SI EL DESPLAZAMIENTO ES CERO (SE HA LLEGADO A NUMERO NUEVE)
00470    LDA #$B0     ;ENTONCES SE CARGA A CON EL DESPLAZAMIENTO PARA EL NUMERO CERO Y
00480    STA PVAR,X   ;SE ALMACENA EN LA POSICION DE LA CIFRA CORRESPONDIENTE
00490B03 CPY #$B8     ;COMPRUEBA SI LA CIFRA QUE APARECE POR ABAJO ES EL CERO
00500    BCS B04      ;SI NO ES ASI SALTA
00510    LDA PVAR     ;SI ES ASI SE LE RESTA OCHO AL DESPLAZAMIENTO PARA PUNTERO CARC PARA
00520    SEC          ;QUE APUNTE ASI A LA ULTIMA POSICION DEL CARACTER SIGUIENTE
00530    SBC #$08     ;DE ORDEN SUPERIOR (POR EJEMPLO EL CARACTER PARA LAS DECENAS)
00540    STA PVAR     ;Y SE GUARDA
00550    LDA PVAR+6   ;SE CARGA A CON EL VALOR DE X ANTES GUARDADO Y SE LE RESTA QUINCE PARA
00560    SBC #$0F     ;QUE EL SCROLL HACIA ARRIBA SE HAGA EN EL SIGUIENTE CARACTER DE ORDEN
00570    TAX          ;SUPERIOR (DESPLAZAMIENTO PARA CARM) Y SE TRANSFIERE A X
00580    DEC PVAR+7   ;SE SITUA PUNTERO EN LA CIFRA SIGUIENTE DE ORDEN SUPERIOR EN LA QUE SE
00590    BNE B01      ;DEBE TRABAJAR Y SALTA PARA DESLIZAR DICHA CIFRA
00600B04 LDA #$20     ;RESTAURA DESPLAZAMIENTO PARA CARC PARA APUNTAR DE NUEVO A
00610    STA PVAR     ;ULTIMA POSICION DEL CARACTER UNIDADES
00620    LDA #$05     ;RESTAURA POSICION DEL CARACTER EN LA QUE SE DEBE TRABAJAR
00630    STA PVAR+7   ;A LA DE UNIDADES
00640    DEC CCAE     ;DECREMENTA NUMERO DE DESLIZAMIENTOS DEL CARACTER Y
00650    BNE B05      ;COMPRUEBA SI SE HA DESLIZADO EL CARACTER COMPLETO SI NO ES ASI SALTA
00660    DEC NCON     ;SI ES ASI DECREMENTA EL NUMERO DE VECES QUE SE HA DE CONTAR EN UNO
00670    LDA #$08     ;RESTAURA EL NUMERO DE DESLIZAMIENTOS A OCHO (EL CARACTER COMPLETO)
00680    STA CCAE     ;
00690B05 LDA #$04     ;RESTAURA EL TEMPORIZADOR
00700    STA TEMP     ;
00710    PLA          ;RECUPERA TODOS LOS REGISTROS DEL STACK
00720    TAX          ;
00730    PLA          ;
00740    TAY          ;
00750B00 PLA          ;
00760    JMP $EA31    ;SALTA A LA RUTINA DE INTERRUPCIONES


RUTINA DE INICIALIZACION DE VARIABLES
=====================================

00000 ; ************************
00010 ; *    NICIALIZACION     *
00020 ; * DE VARIABLES PARA LA *
00030 ; *   RUTINA CONTADOR    *
00040 ; ************************
00050 ;
00060 ;
00070 ; ------------------------
00080 ; *** DEFINE ETIQUETAS ***
00090 ;
00100PVAR .DE $A8 ;
00110TEMP .DE $B1 ;
00120CCAE .DE $B4 ;
00130 ; ------------------------
00140 ;
00150 .BA $106A ; ENSAMBLAR EN $106A
00160 .OS ; ENSAMBLA EN LA MEMORIA
00170 ;
00180    SEI        ;
00190    LDX #$05   ;
00200    LDA #$B0   ;
00210B00 STA PVAR,X ;
00220    DEX        ;
00230    BNE B00    ;
00240    LDA #$04   ;
00250    LDX #$08   ;
00260    LDY #$05   ;
00270    STA TEMP   ;
00280    STX CCAE   ;
00290    STY PVAR+7 ;
00300    LDA #$20   ;
00310    STA PVAR   ;
00320    LDA #$00   ;
00330    STA $0314  ;
00340    LDA #$10   ;
00350    STA $0315  ;
00360    CLI        ;
00370    RTS        ;



COMO CARGAR Y USAR LA RUTINA
============================

CARGAR PRIMERO "CONTADOR+INICIAL",8,1 Y DESPUES "INICIALIZACION",8. UNA VEZ CARGADOS LOS DOS PROGRAMAS HACER 'RUN', EL C64 QUEDARA UNOS SEGUNDOS COMO PARADO, DESPUES IMPRIMIRA LOS CARACTERES DEL CONTADOR Y PONDRA A CERO EL MISMO.

HACIENDO POKE176,XXX EL CONTADOR EMPEZARA A CONTAR, XXX ES CUALQUIER NUMERO DESDE 1 HASTA 255. PARA PONER A CERO EL CONTADOR HACER SYS4202 Y DESPUES POKE176,1.
[/quote]

La tengo en una imagen de disco .d64 si alguno está interesado se la mando.

¡Por cierto! Raúl, el lunes te enviaré algo visible de la carretera.
Commodoriano desde 1986.

lobogris

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 453
  • Programador
    • Ver Perfil
    • http://back2theretro.blogspot.com
Tutorial de ensamblador de C64
« Respuesta #18 en: Abril 16, 2011, 19:44:56 »
pásamelo en .d64 por favor! suena interesante y gracias por compartir tu código maestro :wink: me resulta curioso y muy educativo observar como programan los demás...

Laddh

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 233
    • Ver Perfil
Tutorial de ensamblador de C64
« Respuesta #19 en: Abril 16, 2011, 19:52:16 »
Citar
La tengo en una imagen de disco .d64 si alguno está interesado se la mando

Tenías que haber empezado ya por ahí!!  :D

se agradece la información.

Silicebit

  • Commodorero
  • **
  • Mensajes: 35
    • Ver Perfil
Tutorial de ensamblador de C64
« Respuesta #20 en: Abril 16, 2011, 20:22:11 »
Lobo, esperándote está en tu correo de yahoo  :) .
Commodoriano desde 1986.

lobogris

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 453
  • Programador
    • Ver Perfil
    • http://back2theretro.blogspot.com
Tutorial de ensamblador de C64
« Respuesta #21 en: Abril 16, 2011, 22:05:03 »
gracias ! ya la tengo :)

la acabo de probar y está genial, un efecto muy conseguido!

Silicebit

  • Commodorero
  • **
  • Mensajes: 35
    • Ver Perfil
Tutorial de ensamblador de C64
« Respuesta #22 en: Abril 18, 2011, 21:01:10 »
La verdad es que cuando la terminé y la hice funcionar me sorprendió el efecto tan guapo que tenía.  :)  La desarrollé precisamente como rutina de presentación de la puntuación para algún futuro juego.

¡Con la "DDC" se pueden hacer auténticas virguerías!  :)

Pero.... ¡Eeeeeh! ¡Que tiene copyright!  :lol:

No, ahora en serio, me gustaría saber si se puede hacer más pequeña y más rápida, o de otra forma en la que salga una rutina más pequeña y mejor. ¡¡Soy un maniático de la optimización!!  :D

Raúl, tienes un D64 esperándote en tu correo de retrogamesystem de hotmail.
Commodoriano desde 1986.

Silicebit

  • Commodorero
  • **
  • Mensajes: 35
    • Ver Perfil
Tutorial de ensamblador de C64
« Respuesta #23 en: Abril 18, 2011, 21:18:53 »
Carlos, ya tienes la imagen de disco con la rutina esperando en tu correo.  :)

Saludos.
Commodoriano desde 1986.

Carlos

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 652
    • Ver Perfil
Tutorial de ensamblador de C64
« Respuesta #24 en: Abril 18, 2011, 22:41:06 »
Cita de: "Silicebit"
Carlos, ya tienes la imagen de disco con la rutina esperando en tu correo.  :)

Saludos.


Lo acabo de ver.. quedaría chulo como cuentakilómetros en La Carretera  :wink:

lobogris

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 453
  • Programador
    • Ver Perfil
    • http://back2theretro.blogspot.com
Tutorial de ensamblador de C64
« Respuesta #25 en: Abril 18, 2011, 22:54:36 »
esa rutina desde hace tiempo tambien la tenia pensada hacer para los scores, y no solo para esto, tambien para mejorar un juego simulador de máquina tragaperras que hice hace tiempo, para simular el avance de las frutas.

Una forma fácil de que vaya más rápida, asi de pronto es llamandola
dos veces (o más) en cada golpe de int en lugar de una.

no la he mirado todavia por dentro la rutina, pero imagino que haces una rotación de bloques de 8 bits hacia arriba, en simbolos que no se usan copiando previamente los datos de los simbolos de los numeros en la zona que guarda los datos del juego de caracteres, ¿verdad?

Al menos es lo que yo hubiera hecho. Lo que no entiendo es por que tarda tanto la copia o generación de caracteres en la inicialización, siendo en código máquina... quizá habria que retocar la forma en que se gestionan los bucles de copia, pero tampoco es nada muy serio, teniendo en cuenta que solo ocurre una vez al principio del programa y no tarda una cosa exagerada...

na_th_an

  • Commodorero
  • **
  • Mensajes: 27
    • Ver Perfil
Tutorial de ensamblador de C64
« Respuesta #26 en: Abril 19, 2011, 11:49:11 »
Si no os importa leer en inglés, tengo un par de libros en PDF sobre ensamblador del 6509 que me han ayudado muchísimo. En un par de días fui capaz de pintar un mapeado de tiles en un VIC-20, ahí es nada :)

Silicebit

  • Commodorero
  • **
  • Mensajes: 35
    • Ver Perfil
Tutorial de ensamblador de C64
« Respuesta #27 en: Abril 19, 2011, 18:35:38 »
Cita de: "lobogris"
esa rutina desde hace tiempo tambien la tenia pensada hacer para los scores, y no solo para esto, tambien para mejorar un juego simulador de máquina tragaperras que hice hace tiempo, para simular el avance de las frutas.


La diseñé para eso, para los scores. Poniendo un cero fijo como unidades la rutina contaría de diez en diez, ¡ideal para un buen mata marcianos!  :)


Cita de: "lobogris"
Una forma fácil de que vaya más rápida, asi de pronto es llamandola dos veces (o más) en cada golpe de int en lugar de una.


No hace falta llamarla mas de una vez dentro del IRQ, juega con la variable TEMP y verás.  :wink:


Cita de: "lobogris"
no la he mirado todavia por dentro la rutina, pero imagino que haces una rotación de bloques de 8 bits hacia arriba, en simbolos que no se usan copiando previamente los datos de los simbolos de los numeros en la zona que guarda los datos del juego de caracteres, ¿verdad?

Al menos es lo que yo hubiera hecho. Lo que no entiendo es por que tarda tanto la copia o generación de caracteres en la inicialización, siendo en código máquina... quizá habria que retocar la forma en que se gestionan los bucles de copia, pero tampoco es nada muy serio, teniendo en cuenta que solo ocurre una vez al principio del programa y no tarda una cosa exagerada...


¡¡Exacto!! Se copian los carácteres de la ROM a la RAM, se le dice al VIC que ahora los patrones del juego de carácteres están en la RAM y ahí la rutina trabaja con unos carácteres poco importantes. Pero la copia de la ROM a la RAM la hace un pequeño programa en BASIC, de ahí su lentitud.

Primero se hace un scroll hacia arriba del carácter destino, y después se utiliza un direccionamiento indexado con Y para coger la línea del patrón de bits correspondiente al carácter fuente que debe aparecer por abajo del carácter destino.

En definitiva, se vuelca el contenido de un carácter en otro pero línea a línea. Por supuesto con un algoritmo para que la rutina sepa cuando aparece un cero y acarree una unidad en la cifra de peso superior (cuando pasa del 9 al 10 o del 99 al 100 o ......).
Commodoriano desde 1986.

Silicebit

  • Commodorero
  • **
  • Mensajes: 35
    • Ver Perfil
Tutorial de ensamblador de C64
« Respuesta #28 en: Abril 19, 2011, 18:36:47 »
Cita de: "na_th_an"
Si no os importa leer en inglés, tengo un par de libros en PDF sobre ensamblador del 6509 que me han ayudado muchísimo. En un par de días fui capaz de pintar un mapeado de tiles en un VIC-20, ahí es nada :)


¿Qué libros son esos na_th_an? Por cierto, serán del 6502, no del 6509, imagino.  :)

Puede ser que te confundas con el 6809 de Motorola, otro gran y olvidado microprocesador de 8 bits, mejor aún que el 6502 y el Z80 juntos.  :)
Commodoriano desde 1986.

lobogris

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 453
  • Programador
    • Ver Perfil
    • http://back2theretro.blogspot.com
Tutorial de ensamblador de C64
« Respuesta #29 en: Abril 19, 2011, 21:31:31 »
Cita de: "Silicebit"

utiliza un direccionamiento indexado con Y para coger la línea del patrón de bits correspondiente al carácter fuente que debe aparecer por abajo del carácter destino.


por eso te acordaste de esta rutina al leer lo del direccionamiento indexado Y, ahora entiendo :D

Gracias por las explicaciones.