Commodore manía

Commodore 64 => Desarrollo => Ensamblador => Mensaje iniciado por: Carlos en Julio 01, 2010, 09:37:44

Título: Tutorial de ensamblador de C64
Publicado por: Carlos en Julio 01, 2010, 09:37:44
Últimamente me estoy metiendo mas y mas con rutinas en assembler para el commodore pero todavía tengo demasiadas lagunas con este tema ya que hasta ahora casi todo lo he hecho en C.

¿Conoceis algún tutorial que enseñe lo básico de ensamblador para C64? me refiero a que empiece desde lo más simple, por ejemplo cómo construir comparaciones, bucles, operaciones matemáticas, ...

Busco algo como lo que viene en esta web (http://www.c64.ch/programming/ (http://www.c64.ch/programming/)) pero que esté acabado  :wink: . Me he bajado algún libro de assembler que recomiendan como el de Jim Butterfield pero aunque está bien no acabo de verlo bien estructurado y encontrar lo que busco.
Título: Re: Tutorial de ensamblador de C64
Publicado por: marcos64 en Julio 01, 2010, 22:43:31
Cita de: "Carlos"
por ejemplo cómo construir comparaciones, bucles, operaciones matemáticas, ...


Si has programado en C, primero vas a tener que cambiar el 'enfoque'. Me refiero a que el ensamblador del 6502 tiene unas instrucciones muy simples y hacer operaciones matematicas, por ejemplo calcular el coseno, ya es un programa en si mismo.

Lo comento porque yo estoy en una situacion parecida a la tuya y repasando codigo voy de sorpresa en sorpresa de como programan las cosas.

Primero 'olvida' lo que tienes aprendido porque si quieres programar en assembler como lo haces en C mucho me temo de que no llegaras muy lejos.

Repetire el mejor consejo que he leido: Estudia el codigo que otros han hecho.

Pero respondiendo a tu pregunta leete el manual del Turbo Assembler http://turbo.style64.org/ (http://turbo.style64.org/) y quizas encuentres algo aqui http://codebase64.org/doku.php (http://codebase64.org/doku.php)

Creo que no es lo que tu querias exactamente pero es util para aprender.
Título: Tutorial de ensamblador de C64
Publicado por: josepzin en Julio 02, 2010, 09:09:00
Por lo que recuerdo del Assembler, en realidad es bastante simple, es como dice Marcos64, entender la base del funcionamiento y luego ir viendo para que sirve cada instrucción.

La mayoría de las operaciones sirven para transferir datos de una parte a otra, procesarlos (desplazamientos, ands, ors) y hacer comparaciones entre esos datos... y saltar de aqui para allá.

Y con eso ya se hace todo  :D

Si, creo que lo he simplificado demasiado, pero esa es la sensación/recuerdo que tengo.
Título: Tutorial de ensamblador de C64
Publicado por: Carlos en Julio 02, 2010, 11:57:39
Una pequeña duda estúpida que no acabo de ver, si hago lo siguiente:

[code]lda #$7
sta _var1[/quote]

lo que estoy haciendo es almacenar el valor 7 en la variable 'var1', pero ¿cómo puedo hacer para almacenar el valor 7 en la dirección de memoria apuntada por la variable 'var1'? es decir, supongamos que var1 tiene el valor $9a y yo quiero almacenar el 7 en esa dirección de memoria.
Título: Tutorial de ensamblador de C64
Publicado por: marcos64 en Julio 02, 2010, 16:27:48
Eso no lo tienes que hacer tu, sino que lo hace el macroensamblador que  uses. No es algo que se pueda hacer en assembler 'puro', el assembler no tiene variables, con un monitor de codigo maquina simplemente seria imposible.
Con un ensamblador, como el del link que te he puesto arriba, tu declaras la 'variable' (es un decir, no es una variable como en C, sino algo mucho mas simple) y al 'copilar' el programa el asembler se encarga.
El '7' es un '7' hexadecimal y el simbolo '_' no se si signica algo o es solo un error al teclear?
Y evidentemente puedes hacer un 'sta $9a' , pero me imagino que no es lo que preguntas.
Título: Tutorial de ensamblador de C64
Publicado por: Carlos en Julio 02, 2010, 16:59:19
Cita de: "Marcos64"
Eso no lo tienes que hacer tu, sino que lo hace el macroensamblador que  uses. No es algo que se pueda hacer en assembler 'puro', el assembler no tiene variables, con un monitor de codigo maquina simplemente seria imposible.
Con un ensamblador, como el del link que te he puesto arriba, tu declaras la 'variable' (es un decir, no es una variable como en C, sino algo mucho mas simple) y al 'copilar' el programa el asembler se encarga.
El '7' es un '7' hexadecimal y el simbolo '_' no se si signica algo o es solo un error al teclear?
Y evidentemente puedes hacer un 'sta $9a' , pero me imagino que no es lo que preguntas.


A ver que creo que me he explicado como el culo  :lol: algo de ensamblador si que sé y el código que he puesto antes es perfectamente válido al menos con el cross-assembler que uso (el ca65).

En el ejemplo que he puesto lo que estoy haciendo es asignar un valor (el $7) a una variable, si alguien está familiarizado con el assembler del ca65 y con otros similares si que se pueden usar 'variables' o al menos etiquetas que las simulan (si es que en assembler puro no se puede que eso no lo sabía), mi pregunta era como poder almacenar el valor no en la variable en sí sino en la dirección de memoria que apunta la variable, es decir, en la dirección de memoria que indica el contenido de la variable. Creo que es algún tipo de direccionamiento pero desconozco cómo hacerlo.
Título: Tutorial de ensamblador de C64
Publicado por: josepzin en Julio 02, 2010, 17:12:14
Yo creo que deberias hacer algo asi:

tmp = var
sta tmp

pero no creo que haya una instruccion para hacer eso...
Título: Tutorial de ensamblador de C64
Publicado por: josepzin en Julio 02, 2010, 17:12:52
Una guía básica de ensamblador para 6502 para tener un pantallazo general: http://web.atari.org/ass1paso.txt (http://web.atari.org/ass1paso.txt) (y en castellano)

Lo siento si estoy siendo "captain obvious" :D :D
Título: Tutorial de ensamblador de C64
Publicado por: marcos64 en Julio 03, 2010, 11:51:11
Pues si, vamos a tener un pequeño problema de comunicacion.  :D

Yo entiendo que tu haces lo siguiente:

var1=$9a ;declaras la 'variable' o 'etiqueta'
.
.
.
lda #$07 ; cargas el acumulador con $07
sta var1 ; almacenas el acumulador en var1
.
.
.

entonces al copilar este 'codigo fuente' con un ensamblador que soporte las 'etiquetas' o 'variables' el propio ensamblador sustituye el 'var1' por $9a y al ejecutar ese codigo se realiza la siguiente accion: sta $9a que, si no recuerdo mal, es un direcionamiento directo de pagina cero.
Es decir tu no tienes que hacer nada, si lo tubieras que hacer los ensambladores con estas 'funciones avanzadas' serian de poca utilidad.  :)

De todas formas mejor leerte tranquilamente un buen libro/manual/tutorial de ensamblador porque antes de seguir tienes que conocer las siguientes cosas:
-Instruciones del 6502, y como afectan al registro de estado.
-Modos de direccionamiento.
-El registro de estado.
-Acumulador.
-Registros X e Y.
-PC.
-Pila.
-Memoria.
-Se me olvida algo?
Con esto se hace todo, no hay mas. No se pueden hacer bucles o comparaciones como en lenguajes de alto nivel, sino cosas equivalentes pero mucho, mucho mas sencillas. Y operaciones matematicas pues te tienes que conformas con sumar y restar numeros de 8 bits, aunque tambien puedes hacer divisiones o multiplicacion por 2 desplazando los bits de un byte (logica binaria). Enfin cosas asi.
Quizas ya lo conozcas, no se hasta donde has llegado. Yo mismo aun tengo problemas en comprender como se modifica el registro de estado con algunas instruciones (lo cual hace que no entienda algunas rutinas que me parecen magia).
Y luego esta conocer a fondo el VIC, el SID, las CIAs... Ten en cuenta que muchas cosas que en otros ordenadores de 8 bits necesitan del procesador para realizarse en el 64 las hacen los chips, como por ejemplo lo referente a sprites.
Y disculpa si he contado algunas cosas que son obvias para ti.
Título: Tutorial de ensamblador de C64
Publicado por: Carlos en Julio 06, 2010, 10:37:09
Al parecer la soluci?n a la pregunta que plantee es usar uno de los punteros de la ZP (Zero Page) para acceder mediante ?l al dato que quer?a.
Título: Tutorial de ensamblador de C64
Publicado por: Carlos en Julio 06, 2010, 10:37:25
Al parecer la soluci?n a la pregunta que plantee es usar uno de los punteros de la ZP (Zero Page) para acceder mediante ?l al dato que quer?a.
Título: Tutorial de ensamblador de C64
Publicado por: Carlos en Julio 06, 2010, 10:53:58
Al parecer la soluci?n a la pregunta que plante? era usar un puntero de la ZP (Zero Page) para acceder al dato mediante el mismo.
Título: Tutorial de ensamblador de C64
Publicado por: josepzin en Julio 10, 2010, 12:39:38
¿Podrías poner exactamente cómo es la solución?
Título: Tutorial de ensamblador de C64
Publicado por: Carlos en Agosto 06, 2010, 13:12:55
No tengo ahora el código a mano, pero se basa en usar el modo de direccionamiento Indirecto Indexado del 6510.
Título: Tutorial de ensamblador de C64
Publicado por: josepzin en Agosto 06, 2010, 16:00:40
Si puedes copia ese trocito de código
Título: Tutorial de ensamblador de C64
Publicado por: josepzin 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
Título: Tutorial de ensamblador de C64
Publicado por: lobogris 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...
Título: Tutorial de ensamblador de C64
Publicado por: Silicebit 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.
Título: Tutorial de ensamblador de C64
Publicado por: lobogris 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...
Título: Tutorial de ensamblador de C64
Publicado por: Laddh 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.
Título: Tutorial de ensamblador de C64
Publicado por: Silicebit en Abril 16, 2011, 20:22:11
Lobo, esperándote está en tu correo de yahoo  :) .
Título: Tutorial de ensamblador de C64
Publicado por: lobogris en Abril 16, 2011, 22:05:03
gracias ! ya la tengo :)

la acabo de probar y está genial, un efecto muy conseguido!
Título: Tutorial de ensamblador de C64
Publicado por: Silicebit 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.
Título: Tutorial de ensamblador de C64
Publicado por: Silicebit en Abril 18, 2011, 21:18:53
Carlos, ya tienes la imagen de disco con la rutina esperando en tu correo.  :)

Saludos.
Título: Tutorial de ensamblador de C64
Publicado por: Carlos 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:
Título: Tutorial de ensamblador de C64
Publicado por: lobogris 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...
Título: Tutorial de ensamblador de C64
Publicado por: na_th_an 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 :)
Título: Tutorial de ensamblador de C64
Publicado por: Silicebit 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 ......).
Título: Tutorial de ensamblador de C64
Publicado por: Silicebit 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.  :)
Título: Tutorial de ensamblador de C64
Publicado por: lobogris 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.
Título: Tutorial de ensamblador de C64
Publicado por: Silicebit en Abril 21, 2011, 17:10:59
Cita de: "Silicebit"
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.  :)


¡¡Pues yo estaba equivocado!! Sí existe el 6509.

El MOS 6509 es una versión mejorada del 6502 capaz de direccionar hasta 1MB de memoria mediante conmutación de bancos, como haría cualquier otro 8 bits. Sólo que mientras el 6502 o el Z80 necesitan un chip externo para realizar la conmutación de bancos, el MOS 6509 trae la circuitería necesaria para esa conmutación ya incluida dentro.

El MOS 6509 se usó en los Commodore CBM-II.
Título: Tutorial de ensamblador de C64
Publicado por: na_th_an en Abril 25, 2011, 09:23:14
Cita de: "Silicebit"
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.  :)


Oops, un lápsus de números y memoria :lol: El 2, el 2.

Me ayudó, principalmente, "6502 Machine Language for Beginners", que tenéis online en http://www.6502dude.com/6502/mlb/chapter1.htm (http://www.6502dude.com/6502/mlb/chapter1.htm) . Está todo muy bien explicado.

Luego, el programmer reference guide del VIC-20, que tiene mil y una tablas para que no se te pierda nada. Es específico de este ordenador, pero bueno, yo estaba enredando en este ordenador :D Buscad VIC20PrgRefGuide.txt en Google.

Todas mis pruebas las hice usando el linker y el ensamblador del compilador CC65, que es bastante cómodo para estos manejes (te permite compilar para VIC20 con 8K o 16K de memoria expandida y colocar todo en su sitio: el startup code va el la RAM "normal" y hay una llamada al segmento de memoria expandida donde va todo tu programa. Además, te permite definir un segmento con el juego de caracteres expandido que se coloca en su área correcta de RAM automáticamente. Al final te genera un PRG listo para ejecutar.

Si os interesa el VIC-20 y queréis que os pase todo el "startup code" (que adapté de los fuentes de un juego indie de hace un par de años) no tenéis más que dar un grito :)

En cuanto le pillas el truco a la página cero es genial, es como tener 256 registros por la patilla :D

[code]CLEARSCREEN:
        LDX #$00
        LDY #$14
        STX $FB
        STY $FC         ; FC:FB -> $1400 (character memory)
        LDX #$00
        LDY #$94
        STX $FD
        STY $FE         ; FE:FD -> $9400 (color memory)
        ; 512 vueltas
        LDX #$02
        LDY #$00
@fill:  LDA #$0F
        STA ($FD),Y     ; (FE:FD + Y) <- A
        LDA #$7F
        STA ($FB),Y     ; (FC:FB + Y) <- A
        INY             ; Y ++
        BNE @fill       ; Y != 0 THEN @fill
        INC $FC         ; (FC)++
        INC $FE         ; (FE)++
        DEX             ; X --
        BNE @fill       ; X != 0 THEN @fill
        RTS[/quote]
Título: Tutorial de ensamblador de C64
Publicado por: josepzin en Abril 25, 2011, 13:12:18
Cita de: "na_th_an"

En cuanto le pillas el truco a la página cero es genial, es como tener 256 registros por la patilla :D


¿Cómo es eso??
Título: Tutorial de ensamblador de C64
Publicado por: na_th_an en Abril 26, 2011, 13:39:11
La página cero son los primeros 256 bytes de RAM. El acceso a esta página por parte de la CPU es "especial" y se realiza muy rápidamente (más rápido que un acceso a otra parte de la memoria - según tengo entendido). Es ideal para usar como "buffer de intercambio" para almacenar datos temporales y tal, ya que la CPU tiene muy pocos registros propios.

La principal utilidad es que hay modos de direccionamientos de la CPU que emplean directamente la "zero page", como puedes ver en el pochocódigo que he puesto más arriba. Las operaciones LD o ST que se refieran a (nn),X o (nn),Y están apuntando a la dirección de memoria obtenida de consultar el valor almacenado en (nn+1)*256+nn y sumarle X o Y. Esto te permite almacenar punteros en la zero page y usarlos directamente para escribir o leer de memoria en bucle.

Por ejemplo, si quieres copiar 100 bytes desde $2000 a $3000, por ejemplo, haríamos así:

[code]
        ; Almacenamos en FC:FB el origen $2000
       
        LDX #$00
        LDY #$20
        STX $FB
        STY $FC         ; FC:FB -> $2000
       
        ; Almacenamos en FE:FD el destino $3000
       
        LDX #$00
        LDY #$30
        STX $FD
        STY $FE         ; FE:FD -> $3000
       
        ; Ahora vamos a copiar 100 bytes...
       
        LDX #$64        ; 100 en hexadecimal

        ; Y esta es la chicha:
       
@b1:    LDA ($FB),X     ; Nos traemos a A lo que esté en ($FB)+256*($FC)+X, o sea, $2000+X
        STA ($FD),X     ; Escribimos A en ($FD)+256*($FE)+X, o sea, $3000+X
        DEX             ; X = X - 1
        BNE @b1         ; IF X <> 0 THEN @b1[/quote]

Lo que viene MUY bien.

Al principio se hace uno un lío con los direccionamientos, pero una vez que le coges el truco te das cuenta de que todo es muy sencillo y está muy bien diseñado. Un 10 para el 6502.

Sólo hay que tener en cuenta que el C64 usa muchas de las direcciones de la página cero para sus cosas, así que si quieres hacer juegos que funcionen bien con las rutinas del Kernel o como se llame tienes que respetarlo. Si, por el contrario, vas a tomar total control sobre la máquina, puedes pasar de ellos.