Commodore manía
Commodore 64 => Desarrollo => CC65 => Mensaje iniciado por: kerunaru en Junio 26, 2011, 10:17:10
-
Buenas gente,
Estoy empezando a usar herramientas de hoy para programar en hardware de ayer! xD Estoy usando el cc65 y MacVim.
Tengo este programa:
[code];
inc $D020
jmp $2000[/quote]
Es muy simplón, pero es que quiero aprender a usar el cc65. Para compilarlo hago lo siguiente:
[code]ca65 -t c64 test.a[/quote]
Y luego le hago un:
[code]ld65 -t c64 -o test test.o[/quote]
Pero el ld65 me da el siguiente warning:
[code]ld65: Warning: [builtin config](6): Segment `STARTUP' does not exist
ld65: Warning: [builtin config](12): Segment `ZPSAVE' does not exist
[/quote]
¿Alguien sabe qué significa?
-
Seguramente Carlos lo sepa!
-
Podrías postear el código assembler completo?
El fallo que da es que no encuentra dos segmentos del fichero de configuración del linker, se me ocurre que estes usando algo de la librería de c64, prueba a linkar así:
[code]ld65 -t c64 -o test test.o c64.lib[/quote]
-
No es eso y el código es ese, no tiene más... Simplemente cambia el color del borde de la pantalla.
¿Qué es ese segmento STARUP que menciona? ME da la sensación de que me falta algo por picar... :(
-
No es eso y el código es ese, no tiene más... Simplemente cambia el color del borde de la pantalla.
Sigo diciéndote que si pegas TODO el fuente es más fácil que pueda ayudarte...
¿Qué es ese segmento STARUP que menciona? ME da la sensación de que me falta algo por picar... :(
http://www.cc65.org/doc/ld65-6.html (http://www.cc65.org/doc/ld65-6.html)
-
Sigo diciéndote que si pegas TODO el fuente es más fácil que pueda ayudarte...
Lo mismo no me he explicado bien..
[code]inc $D020
jmp $2000[/quote]
Eso es lo que tengo, 2 líneas en ensamblador, nada más... He estado programando directamente en ensamblador en el VICE usando el supermon y ahora estoy intentando pasarme a entornos modernos...
-
Ok, para empezar lo que te da son 2 warnings (no son errores) y si te fijas te crea el fichero ejecutable.
Para entender bien el problema te aconsejo que te leas con detenimiento toda la parte del cc65 relativa a la configuración de memoria y los segmentos, es la clave para entender esta suite de cross-compiler/assembler/linker.
Lo que estas haciendo con esta orden: [code]ld65 -t c64 -o test test.o[/quote] es linkar el programa objeto usando el mapa de configuración de memoria del c64 por defecto que trae el linker (se lo estas diciendo con el parámetro -t c64). Si quieres ver en que consiste este mapa por defecto sólo tienes que usar el comando: [code]ld65 --dump-config c64[/quote]
Puedes ver que en ese mapa de configuración existen, entre otros, dos segmentos llamados STARTUP y ZPSAVE. Creo que es necesario definir esos dos segmentos en tu código (ahora hablo un poco de memoria) y como no lo has hecho por eso te da los warnings.
-
Comprendo... Seguiré investigando. A ver si encuentro código de ejemplo; eso me ayudaría mucho.
¡Gracias! :D
-
Una materia pendiente esto de los segmentos...
-
Básicamente los segmentos no son más que definiciones que emplea el linker para colocar el código ensamblado. Esto, por ejemplo, en un VIC20, es muy necesario, porque la configuración que tiene de memoria no es continua y no puedes colocar lo que te dé la gana donde quieras.
Por ejemplo, si generas ejecutables para un VIC-20 expandido (con 8Kb por ejemplo), los segmentos se emplean para especificar cómodamente qué código va en la RAM principal, dónde se ubica la memoria de color y la de caracteres, y qué código va en la ram expandida.
Por ejemplo, en la configuración de memoria que uso para VIC-20 (bueno, que uso es un decir, porque la "usé" para hacer pruebas pero, por falta de tiempo, lo tengo bastante abandonado), primero se define el mapa de memoria:
MEMORY {
RAM0: start = $0400, size = $0C00, type = rw;
RAM: start = $11FF, size = $0201, type = rw, fill = yes;
SCR: start = $1400, size = $0400, type = ro, fill = yes;
BUF: start = $1800, size = $0400, type = rw, fill = yes;
CHAR: start = $1C00, size = $0400, type = rw, fill = yes;
RAM1: start = $2000, size = $2000, type = rw;
RAM2: start = $4000, size = $2000, type = rw;
RAM3: start = $6000, size = $2000, type = rw;
RAM4: start = $8000, size = $2000, type = rw;
ROM1: start = $A000, size = $1000, type = ro;
ROM2: start = $B000, size = $1000, type = ro;
}
Básicamente especifica qué tipo de memoria hay en cada intervalo, cuanto ocupa, y si es de escritura, o de sólo lectura, etc. Luego, sobre ese mapa de memoria, ubicamos nuestros segmentos:
SEGMENTS {
BASIC: load = RAM, type = ro, define = yes, optional = no;
STARTUP: load = RAM, type = ro, define = yes, optional = no;
MYCHAR: load = CHAR, type = rw, define = yes, optional = no;
CODE: load = RAM1, type = ro, define = yes, optional = no;
}
Se definen cuatro segmentos: el segmento BASIC y STARTUP se definen en la RAM principal. El segmento MYCHAR, donde irá la definición de mi set de caracteres, se coloca en la zona CHAR. Por último, el segmento CODE se coloca en la ram expandida, o sea, RAM1 del mapa de memoria.
Por último, se define el punto de entrada del autoejecutable:
FEATURES {
STARTADDRESS: default = $11FF;
}
Como véis, apunta al principio de la zona RAM.
Luego, en tu código, sólo indicas en qué segmento estás colocando cada cosa. Primero se define lo que hay en el segmento "BASIC", que es código BASIC a pelo. Este código llama al programa en ML:
.segment "BASIC"
.word RUN ; load address
RUN: .word END ; next line link
.word 2010 ; line number
.byte $9E ; BASIC token: SYS
.byte <(MAIN / 1000 .mod 10) + $30
.byte <(MAIN / 100 .mod 10) + $30
.byte <(MAIN / 10 .mod 10) + $30
.byte <(MAIN / 1 .mod 10) + $30
.byte 0 ; end of line
END: .word 0 ; end of program
La directivao .segment "BASIC" lo que hará será ensamblar el código que venga debajo en la zona de RAM donde esté definido dicho segmento.
A continuación se define el código que va en el segmento "STARTUP", que lo que hace es iniciar el VIC y saltar al programa principal, que está en la RAM expandida:
.segment "STARTUP"
MAIN:
LDA #$00+$16 ; set for videoram @ $1400 with 22-columns
STA VIC+$02 ; video matrix address + columns
LDA #%10101110 ; 8x8 height + 23-rows
STA VIC+$03 ; rows / character height
LDA #$DF ; set video @ $1400 and char table @ $1C00
STA VIC+$05
LDA #%01101111 ; Programmer's Reference Guide: Appendix B
STA VIC+$0F
LDA #$FF
STA VIC+$0E
.global MTMYSTART ; useful symbol for MAP and hotkey restarting
JMP MTMYSTART ; the entry point into your program
Luego defino mi set de carácteres, en el segmento MYCHAR, que se colocará, tal y como hemos definido, en el lugar correcto:
.segment "MYCHAR"
SP_PL_R_1:
.byte %00000000
.byte %00001010
.byte %00101010
.byte %00101010
.byte %00101010
.byte %10101001
.byte %10100100
.byte %00101100
.byte %00000000
.byte %10100000
.byte %10101000
.byte %10101000
.byte %10101000
.byte %01010100
.byte %01000100
.byte %11001100
(etcétera)
Y, por último, poblamos el segmento CODE, situado en la RAM expandida, con el código del juego:
.segment "CODE"
MTMYSTART:
JSR CLEARSCREEN
LDA #2
STA TX
STA TY
LDA #0
STA TN
JSR VIC_PSPRITE
(etcétera)
Al ensamblar todo esto, los cachos de código objeto se colocarán en las ubicaciones correctas y todo irá como la seda. Es una forma muy cómoda de organizar la memoria sin tener que hacerlo manualmente generando varios binarios y toda la pesca.
Para un C64 será algo parecido, teniendo en cuenta el mapa de memoria de este sistema.
Haciendo una "adivinación valiente", yo diría que, para el ejemplo del que trata este hilo, bastaría con modificar el fuente para que se pareciese a:
.segment STARTUP
inc $D020
jmp $2000
.segment ZPSAVE
Supongo que ZPSAVE (con ZP = ZERO PAGE) será para dar de un plumazo valor a todas las direcciones importantes de la ZP.
-
GRA - CIAS!
Este post ha sido muy didáctico. Ahora entiendo lo de los segmentos y como compila el cc65 el ensamblador. :D
-
na_th_an te acaba de explicar lo que a mi me daba una pereza terrible... :lol:
-
¡Que grande el nathan!
na_th_an te acaba de explicar lo que a mi me daba una pereza terrible... :lol:
juasss
-
Yo y mi incontinencia verbal :lol: