Commodore manía
Commodore 64 => Desarrollo => CC65 => Mensaje iniciado por: Saffron en Abril 09, 2012, 14:40:32
-
Hola a todos estoy usando el compilador cruzado cc65 y no se como integrar en mi código una rutina para reproducir SID, tampoco encuentro ningún ejemplo en la web. ¿Alguno con experiencia en el tema?
-
Ante todo: ¡bienvenido a C=Mania!
A ver si alguno de los maquinas te puede responder, yo hice algunas pruebas con el cc65 pero mi nivel es bajisimo.
-
Quieres incorporar música SID ya hecha (por ejemplo de un archivo .SID)? O crear tu propia rutina de reproducción para tocar música de tu creación?
Son dos cosas muy distintas.
-
Quiero incorporar algún SID ya hecho, pero me gustaría aprender a poner temas que yo mismo componga con el goat tracker.
-
Ah, entonces en este caso es lo mismo usar un SID ya hecho o la salida del goattracker.
No uso CC65 por lo que no puedo indicarte la sintaxis exacta para incluir o linkear la musica. Pero si lo pasos a seguir para reproducir musica.
(Presupongo que el linker se hace cargo de relocalizar el codigo C a un lugar adecuado para que no interfiera con codigo en assembler)
Usando el SidPlay2W cargas el SID que quieres usar y luego seleccionas File->Properties... y anotas las direcciones que aparecen (Load Range, Init Address y Play Address)
Load Range puede que no lo necesites ya que el linker se debe hacer cargo de esto.
Init Address es la rutina que debes llamar al principio para inicializar el reproductor.
Y Play Address es la direccion que tienes que llamar periodicamente para que la musica suene.
Estas direcciones son especificas de cada SID, y dependen de que editor si uso para crear la musica.
Luego de tener las direcciones usas File->Convert... para convertir el archivo .SID en .DAT (Seleccionando "C64Data (.DAT)" donde dice "Save to type").
Este archivo .DAT resultante es el que usaras para linkear al programa en C.
En tu programa debes hacer 2 cosas:
en un main() llamar a la init address:
__asm__( "jsr init_address" );
Luego tienes que hacer tu propia rutina de interrupción se ejecute 50 o 60 veces por segundo, dentro de la cual tienes que llamar a play_address
por ejemplo, creas un nuevo archivo irq.s conteniendo lo siguiente:
.export _setup_irq
_setup_irq:
sei
lda #<irq
ldx #>irq
sta $314
sta $315
cli
rts
irq:
jsr play_address
rti
Y en tu programa en C, cuando quieres que se comience a reproducir la música llamas a setup_irq:
setup_irq();
Luego al momento de compilar, linkeas tu programa en C, el irq.s y el .DAT
Y eso es todo, la música sonará de fondo sin interrumpir el programa principal.
-
...
(Presupongo que el linker se hace cargo de relocalizar el codigo C a un lugar adecuado para que no interfiera con codigo en assembler)
...
Load Range puede que no lo necesites ya que el linker se debe hacer cargo de esto.
Init Address es la rutina que debes llamar al principio para inicializar el reproductor.
Y Play Address es la direccion que tienes que llamar periodicamente para que la musica suene.
Estas direcciones son especificas de cada SID, y dependen de que editor si uso para crear la musica.
...
Casi seguro que el linker del cc65 no va a relocarlo automaticamente, probablemente tendrá que modificar el fichero de configuración del linker (.cfg) y definir un segmento donde se vaya a ubicar el SID.
-
Muchas gracias por la ayuda compañeros, unas indicaciones como esas era justo lo que necesitaba, en cuanto lo consiga hacer funcionar os cuento el resultado.
-
Bueno el programa compila pero no funciona, al llamar a setup_irq() el programa vuelve al interprete de basic, y dependiendo del sid puede que salte al llamar a la init_address.
En los .SID que estoy probando la init_address es $1000 y la play_address es $1003. Para incluir los datos en el fichero irq.s uso:
.org $1000
.incbin "999.dat"
Con .org se indica al linker que debe cargar en la posición $1000. Las llamada a la inicialización de la rutina sería:
asm("jsr $1000");
En el .c también declaro la función de ensamblador que esta en el irq.s
extern void setup_irq();
-
Recuerda que el archivo .dat tiene los 2 primeros bytes como la dirección de carga igual que un archivo .prg normal
prueba con:
.org $1000
.incbin "999.dat",2
Tambien me olvide de comentar que si el SID que vas a usar tiene más de 1 subtune (como es el caso de SID de juegos), o esta hecho con un tracker que soporta subtunes (Como el Goattracker), tienes que llamar a init_address con el numero de subtune en acumulador comenzando por cero, por ej:
__asm__ ("lda #$00");
__asm__ ("jsr init_address");
-
Bueno pues parece que el linker del cc65 pasa de las directivas .ORG, que solo afectan al ensamblador. Si cargo el sid en el emulador renombrando el fichero 999.DAT como 999.prg y veo las posiciones de memoria $1000 y $1003 veo este código:
$1000 jmp 1070
$1003 jmp 1074
Que no coincide con el código generado con el cc65, poniendo basura en donde debería estar la rutina del sid. Tendré que mirar como hacerlo con un fichero de configuración pero no encuentro información al respecto.
-
La url con la documentación: http://www.cc65.org/doc/ (http://www.cc65.org/doc/) y especificamente la parte de configuración del linker: http://www.cc65.org/doc/ld65-5.html (http://www.cc65.org/doc/ld65-5.html)
-
Uff gracias Carlos, la verdad es que viendo lo complejo es casi que retomo mi aprendizaje de ensamblador :o