C64-Baugruppe Rendern eines Sprites

8

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ß $FFund 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 runnach 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:

Programm läuft in VICE

Was vermisse ich?

Woodrow Barlow
quelle
1
Oh, die Erinnerungen. Natürlich haben wir uns damals nicht mit verrückten Linker-Sachen angelegt :) Wie auch immer, lassen Sie mich einen Blick darauf werfen. Für den Anfang haben Sie die X / Y-Register falsch. Sie sollten $ d000 und $ d001 sein.
Jester
@ Jester danke für den Blick! Ja, das Linker-Zeug hat eine Weile gebraucht, um den Dreh raus zu bekommen. Viele Ratschläge online verwendeten .orgRichtlinien oder stellen den PC direkt ein, um zu steuern, wo Dinge gespeichert werden. ca65rä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.
Woodrow Barlow
@Jester Ich sollte hinzufügen, dass 99% dieses Linker-Skripts direkt von ca65 stammen - alles, was ich hinzugefügt habe, war das Segment "GFXDATA".
Woodrow Barlow
2
@Narr oh mein Gott, ich war mir sicher, dass ich diese Register dreimal überprüft hatte. Ich habe gerade meinen Code aktualisiert, um die richtigen X- und Y-Register zu verwenden ... und es funktioniert perfekt. Ich kann nicht glauben, dass ich zwei Nachmittage damit verbracht habe und das nicht bemerkt habe.
Woodrow Barlow
1
Nur für den Fall, dass Sie sich nicht bewusst sind - es gibt Retrocomputing.SE , wo die Leute dieses Zeug lieben.
tum_

Antworten:

5

Wie @Jester in den Kommentaren hervorhob, sind die Speicheradressen in X- und Y-Position falsch. Die richtigen Adressen sind $d000und $d001:

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

Dies ist der korrigierte Code:

    .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

Und hier ist ein Bild davon in Aktion:

Woodrow Barlow
quelle
Bitte missbrauchen Sie nicht die "Community Wiki" -Funktion. Diese Antwort hat nichts damit zu tun.
Pipe
1
@pipe warum nicht? Narr beantwortete die Fragen in den Kommentaren. Ich lud ihn ein, es als Antwort zu posten. er hat nicht. Also habe ich es gepostet, aber da ich nicht derjenige war, der die Antwort gefunden hat, schien es mir nicht angemessen, meinen Namen darauf zu setzen.
Woodrow Barlow
1
In diesem Thread heißt es, dass der richtige Zeitpunkt für die Verwendung eines Community-Wikis "ist, wenn Ihre Antwort lediglich aus dem zusammengestellt wird, was bereits von anderen in Kommentaren beantwortet wurde".
Woodrow Barlow
1
Dieser Thread mit noch mehr Upvotes geht sogar so weit zu sagen, dass es immer in Ordnung ist, eine Antwort in ein Community-Wiki zu geben, wenn Sie möchten.
Woodrow Barlow
2

Sie können VIC_SPR0_X und VIC_SPR0_Y verwenden, wenn Sie einschließen c64.inc. Dies kann Ihr Leben viel einfacher machen.

Polluks
quelle
Guter Tipp, danke! Ich werde das in Zukunft tun. Sie können dies gerne zur Community-Wiki-Antwort hinzufügen, wenn Sie möchten.
Woodrow Barlow