Я написал короткую программу на ассемблере 6502 для Commodore 64, используя ca65 ассемблер и ld65 linker . Программа должна визуализировать solid квадратный спрайт где-то рядом с центром дисплея, но я не вижу ничего визуализируемого.
Это моя сборка:
.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
Это мой скрипт компоновщика, адаптированный из рекомендованного скриптом компилятора ca65 для рукописного ассемблера на c64 . Единственное изменение, которое я сделал, было добавление сегмента «GFXDATA», чтобы я мог хранить свои спрайты по адресу $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;
}
Это команда, которую я использую для компиляции и компоновки:
cl65 -o graphics.prg --mapfile graphics.map -u __EXEHDR__ -t c64 -C linker.cfg graphics.asm
Это содержимое файла карты после компиляции:
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)
И шестнадцатеричная запись конечного двоичного файла:
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
Сегмент "GFXDATA" мой спрайт Спрайт составляет 64 байта $FF
, поэтому он должен выглядеть как квадрат solid. Эти данные спрайта расположены по адресу $2000
.
. Сегмент "CODE" начинается с обычного начального местоположения BASI C, а ca65 вставляет загрузчик BASI C для меня, поэтому я могу просто введите run
после загрузки программы.
Я не переключил банк VI C, поэтому экран все еще находится в диапазоне адресов по умолчанию ($0400-$07FF
), с последними 8 байтами этот диапазон - мои спрайтовые указатели. Я использую только указатель спрайта 0 ($07f8
), потому что у меня только один спрайт.
Когда я запускаю программу, все блокируется - что и следовало ожидать, потому что программа заканчивается в бесконечном л oop. Но я нигде не вижу спрайт на экране:
Чего мне не хватает?