Сборка C64, представляющая спрайт - PullRequest
8 голосов
/ 14 февраля 2020

Я написал короткую программу на ассемблере 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. Но я нигде не вижу спрайт на экране:

Program running in VICE

Чего мне не хватает?

Ответы [ 2 ]

5 голосов
/ 14 февраля 2020

Как отметил @Jester в комментариях, адреса памяти X-позиции и Y-позиции неверны. Правильные адреса: $d000 и $d001:

; set x and y position
lda #$80
sta $d000
sta $d001

Это исправленный код:

    .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 $d000
    sta $d001

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

И вот его изображение в действии:

2 голосов
/ 28 февраля 2020

Вы можете использовать VIC_SPR0_X и VIC_SPR0_Y, если вы включите c64.inc. Это может сделать вашу жизнь намного проще.

...