Tôi đã viết một chương trình ngắn trong trình biên dịch 6502 cho Trình biên dịch 64 bằng cách sử dụng trình biên dịch ca65 và trình liên kết ld65 . Chương trình sẽ hiển thị một hình vuông đặc ở đâu đó gần trung tâm của màn hình, nhưng tôi không thấy bất cứ điều gì được hiển thị.
Đây là hội đồng của tôi:
.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
Đây là tập lệnh liên kết của tôi, được điều chỉnh từ tập lệnh liên kết được đề xuất của ca65 cho trình biên dịch viết tay trên c64 . Thay đổi duy nhất tôi đã thực hiện là thêm phân đoạn "GFXDATA", để tôi có thể lưu trữ các họa tiết của mình tại địa chỉ $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;
}
Đây là lệnh tôi đang sử dụng để biên dịch và liên kết:
cl65 -o graphics.prg --mapfile graphics.map -u __EXEHDR__ -t c64 -C linker.cfg graphics.asm
Đây là nội dung của mapfile sau khi biên dịch:
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)
Và một hexdump của tệp nhị phân cuối cùng:
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
Phân đoạn "GFXDATA" là sprite của tôi. Sprite là 64 byte $FF
, vì vậy nó sẽ trông giống như một hình vuông rắn. Dữ liệu sprite này được đặt tại địa chỉ $2000
.
Đoạn "MÃ" được bắt đầu tại vị trí bắt đầu BASIC thông thường và ca65 đang chèn trình tải BASIC cho tôi để tôi chỉ cần nhập run
sau khi tải chương trình.
Tôi chưa chuyển ngân hàng của VIC, vì vậy màn hình vẫn ở dải địa chỉ mặc định ( $0400-$07FF
), với 8 byte cuối cùng của phạm vi này là con trỏ sprite của tôi. Tôi chỉ sử dụng con trỏ sprite 0 ( $07f8
) vì tôi chỉ có một sprite.
Khi tôi chạy chương trình, mọi thứ sẽ khóa - đó là điều được mong đợi, bởi vì chương trình kết thúc trong một vòng lặp vô hạn. Nhưng tôi không thấy sprite ở bất cứ đâu trên màn hình:
Tôi đang thiếu gì?
.org
hoặc đặt PC trực tiếp để kiểm soát nơi mọi thứ được lưu trữ. ca65
Mặc dù vậy, không khuyến khích điều này, cho rằng cách thích hợp để kiểm soát nơi mọi thứ được đặt trong nhị phân là sử dụng các tập lệnh liên kết. và bây giờ tôi (tôi nghĩ?) đã thiết lập trình liên kết chính xác, tôi thấy quan điểm của họ - việc tổ chức mọi thứ dễ dàng hơn nhiều.