He escrito un breve programa en el ensamblador 6502 para el Commodore 64 usando el ensamblador ca65 y el enlazador ld65 . El programa debería representar un sprite cuadrado sólido en algún lugar cerca del centro de la pantalla, pero no veo nada renderizado.
Esta es mi asamblea:
.segment "CODE"
; set sprite pointer index
; this, multiplied by $40, is the address
; in this case, the address is $2000
; $80 * $40 = $2000
lda #$80
sta $07f8
; enable sprite 0
lda #$01
sta $d015
; set x and y position
lda #$80
sta $d001
sta $d002
loop:
jmp loop
.segment "GFXDATA"
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
Este es mi script enlazador, adaptado del script enlazador recomendado de ca65 para ensamblador escrito a mano en el c64 . El único cambio que hice fue agregar el segmento "GFXDATA", para poder almacenar mis sprites en la dirección $2000
.
FEATURES {
STARTADDRESS: default = $0801;
}
SYMBOLS {
__LOADADDR__: type = import;
}
MEMORY {
ZP: file = "", start = $0002, size = $00FE, define = yes;
LOADADDR: file = %O, start = %S - 2, size = $0002;
MAIN: file = %O, start = %S, size = $D000 - %S;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, optional = yes;
LOADADDR: load = LOADADDR, type = ro;
EXEHDR: load = MAIN, type = ro, optional = yes;
CODE: load = MAIN, type = rw;
RODATA: load = MAIN, type = ro, optional = yes;
DATA: load = MAIN, type = rw, optional = yes;
GFXDATA: load = MAIN, type = ro, optional = yes, start = $2000;
BSS: load = MAIN, type = bss, optional = yes, define = yes;
}
Este es el comando que estoy usando para compilar y vincular:
cl65 -o graphics.prg --mapfile graphics.map -u __EXEHDR__ -t c64 -C linker.cfg graphics.asm
Este es el contenido del archivo de mapa después de compilar:
Modules list:
-------------
graphics.o:
CODE Offs=000000 Size=000015 Align=00001 Fill=0000
GFXDATA Offs=000000 Size=000040 Align=00001 Fill=0000
/usr/share/cc65/lib/c64.lib(exehdr.o):
EXEHDR Offs=000000 Size=00000C Align=00001 Fill=0000
/usr/share/cc65/lib/c64.lib(loadaddr.o):
LOADADDR Offs=000000 Size=000002 Align=00001 Fill=0000
Segment list:
-------------
Name Start End Size Align
----------------------------------------------------
LOADADDR 0007FF 000800 000002 00001
EXEHDR 000801 00080C 00000C 00001
CODE 00080D 000821 000015 00001
GFXDATA 002000 00203F 000040 00001
Exports list by name:
---------------------
__EXEHDR__ 000001 REA __LOADADDR__ 000001 REA
Exports list by value:
----------------------
__EXEHDR__ 000001 REA __LOADADDR__ 000001 REA
Imports list:
-------------
__EXEHDR__ (exehdr.o):
[linker generated]
__LOADADDR__ (loadaddr.o):
[linker generated] linker.cfg(5)
Y un hexdump del archivo binario final:
0000000 0801 080b 0320 329e 3630 0031 0000 80a9
0000010 f88d a907 8d01 d015 80a9 018d 8dd0 d002
0000020 1f4c 0008 0000 0000 0000 0000 0000 0000
0000030 0000 0000 0000 0000 0000 0000 0000 0000
*
0001800 ff00 ffff ffff ffff ffff ffff ffff ffff
0001810 ffff ffff ffff ffff ffff ffff ffff ffff
*
0001840 00ff
0001841
El segmento "GFXDATA" es mi sprite. El sprite tiene 64 bytes $FF
, por lo que debería verse como un cuadrado sólido. Estos datos de sprite se encuentran en la dirección $2000
.
El segmento "CÓDIGO" se inicia en la ubicación de inicio BASIC habitual, y ca65 está insertando un cargador BASIC para mí, así que puedo escribir run
después de cargar el programa.
No he cambiado el banco de VIC, por lo que la pantalla todavía está en su rango de dirección predeterminado ( $0400-$07FF
), con los últimos 8 bytes de este rango como mis punteros de sprite. Solo estoy usando el puntero de sprite 0 ( $07f8
) porque solo tengo un sprite.
Cuando ejecuto el programa, todo se bloquea, lo cual es de esperar, porque el programa termina en un bucle infinito. Pero no veo el sprite en ninguna parte de la pantalla:
¿Qué me estoy perdiendo?
.org
directivas o configuran la PC directamente para controlar dónde se almacenan las cosas. ca65
Sin embargo, desalienta esto, argumentando que la forma correcta de controlar dónde se colocan las cosas en el binario es usar scripts de enlazador. y ahora que tengo (creo) la configuración del enlazador correctamente, veo su punto: es mucho más fácil organizar todo.