Ich habe ein kurzes Programm in 6502 Assembler für den Commodore 64 mit dem Ca65 Assembler und dem LD65 Linker geschrieben . Das Programm sollte irgendwo in der Mitte der Anzeige ein durchgehendes quadratisches Sprite rendern, aber ich sehe nichts, was gerendert wird.
Dies ist meine Versammlung:
.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
Dies ist mein Linker-Skript, angepasst an das von ca65 empfohlene Linker-Skript für handgeschriebene Assembler auf dem c64 . Die einzige Änderung, die ich vorgenommen habe, war das Hinzufügen des Segments "GFXDATA", damit ich meine Sprites unter der Adresse speichern konnte $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;
}
Dies ist der Befehl, den ich zum Kompilieren und Verknüpfen verwende:
cl65 -o graphics.prg --mapfile graphics.map -u __EXEHDR__ -t c64 -C linker.cfg graphics.asm
Dies ist der Inhalt der Map-Datei nach dem Kompilieren:
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)
Und ein Hexdump der endgültigen Binärdatei:
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
Das Segment "GFXDATA" ist mein Sprite. Das Sprite ist 64 Byte groß $FF
und sollte daher wie ein festes Quadrat aussehen. Diese Sprite-Daten befinden sich unter der Adresse$2000
.
Das "CODE" -Segment wird an der üblichen BASIC-Startposition gestartet, und ca65 fügt einen BASIC-Loader für mich ein, damit ich run
nach dem Laden des Programms einfach tippen kann .
Ich habe die Bank des VIC nicht gewechselt, daher befindet sich der Bildschirm immer noch im Standardadressbereich ( $0400-$07FF
), wobei die letzten 8 Bytes dieses Bereichs meine Sprite-Zeiger sind. Ich verwende nur den Sprite-Zeiger 0 ($07f8
), weil ich nur ein Sprite habe.
Wenn ich das Programm starte, stürzt alles ab - was zu erwarten ist, da das Programm in einer Endlosschleife endet. Aber ich sehe das Sprite nirgendwo auf dem Bildschirm:
Was vermisse ich?
.org
Richtlinien oder stellen den PC direkt ein, um zu steuern, wo Dinge gespeichert werden.ca65
rät jedoch davon ab, zu argumentieren, dass der richtige Weg, um zu steuern, wo Dinge in der Binärdatei platziert werden, die Verwendung von Linker-Skripten ist. und jetzt, wo ich (glaube ich?) das Linker-Setup richtig eingestellt habe, verstehe ich ihren Punkt - es ist viel einfacher, alles zu organisieren.Antworten:
Wie @Jester in den Kommentaren hervorhob, sind die Speicheradressen in X- und Y-Position falsch. Die richtigen Adressen sind
$d000
und$d001
:Dies ist der korrigierte Code:
Und hier ist ein Bild davon in Aktion:
quelle
Sie können VIC_SPR0_X und VIC_SPR0_Y verwenden, wenn Sie einschließen
c64.inc
. Dies kann Ihr Leben viel einfacher machen.quelle