Ассемблер ca65 и линкер ld65
Я начинаю использовать ассемблер ca65 и компоновщик ld65 в Windows для создания двоичного кода для компьютера Commodore C64, работающего на эмуляторе VICE.
Я пишу этот маленький "привет мир" источник в файле "basic2.s"
;--------------------------------------
; objetivo: assembly a header BASIC program
; to run binary code
;
; assembler: ca65
; http://cc65.github.io/doc
;
; v101-c101 2018-08-09 13:50:53 A.Alonso
;-----------------------------------------------------
PRINTTOKEN = $99
SYSTOKEN = $9e
chrout = $ffd2
.org $0801
;
Linea10: .word Linea20
.word 10
.byte PRINTTOKEN
.byte 39," NOMBRE PROGRAMA ",39
.byte 0
;--
Linea20: .word LineaEnd
.word 20
.byte SYSTOKEN
.byte " 2089"
.byte 0
;--
LineaEnd: .word 0 ; fin de lineas
.word 0 ; fin de programa
;--
;
Main: ldx #0
ciclo1: lda saludo,x
jsr chrout
inx
cpx #<(saludofin-saludo)
bcc ciclo1
salida: rts
saludo: .byte "--- HOLA MUNDO! -----"
saludofin: .byte 0
Я могу собрать с помощью команды:
ca65 -t c64 basic2.s
И генерировать "basic2.o"
Я читаю документацию линкера ld65 и это сбивает с толку
Я попытался безуспешно:
1-С командой
ld65 basic2.o
ошибка:
ld65: Error: Memory configuration missing
2-С командой
ld65 -C c64-asm.cfg basic2.o
ошибка:
ld65: Warning: c64-asm.cfg(21): Segment `LOADADDR' does not exist
Unresolved external `__LOADADDR__' referenced in:
c64-asm.cfg(5)
ld65: Error: 1 unresolved external(s) found - cannot create output file
Спасибо
3 ответа
Документация немного разбросана, но она есть, если вы посмотрите достаточно внимательно.
Когда вы указываете конфигурацию, она определяет формат выходного объекта. А в c64-asm.cfg есть:
__LOADADDR__: type = import;
Этот конфиг ожидает, что что-то экспортирует LOADADDR, чтобы он мог построить заголовок PRG. Если вы связываетесь с c64.lib (и т. Д.), То он экспортирует его (жестко запрограммировано до $801). В противном случае вам нужно поставить его самостоятельно.
Один из способов - использовать командную строку с параметром --start-addr, как предлагают Лоран Х. и документы, но это довольно сложно. Вместо этого вы можете получить исходный язык ассемблера для его экспорта. Я плохо знаю CC65, но:
.org $0801
.export LOADADDR = *
Также вы можете построить в одну строку:
cl65.exe -o basic2.prg -t c64 -C c64-asm.cfg basic2.s
Вот как я могу настроить свою среду сборки. Я пишу для пользовательского SBC 6502, который я разработал (не Commodore 64), но техника очень похожа. У меня есть небольшая программа под названием "mon.asm" (для монитора). Кроме того, в моем каталоге проектов у меня есть пара рабочих каталогов, называемых tmp
а также dist
, Tmp - это место, куда идут *.o (объектные) файлы и другие временные рабочие файлы. В папке dist находится мой готовый двоичный файл (файл, который я на самом деле записываю в EEPROM).
Сначала я настроил make.cmd
задание по настройке переменной среды, сборке, связыванию и т. д. Это задание очищает мои папки и создает / связывает двоичный файл.
make.cmd
@echo off
REM Set some local variables
set loc=..\bin\cc65-snapshot-win32\bin
set dist=dist
set tmp=tmp
REM Clean
del /Q "%dist%"
del /Q "%tmp%"
REM Assemble and Link
"%loc%\ca65.exe" -D mon "mon.asm" -o "%tmp%\mon.o"
"%loc%\ld65.exe" -C "mon.cfg" "%tmp%\mon.o" -o "%dist%\mon.bin" -Ln "%tmp%\mon.lbl"
Обратите внимание, что в файле есть пара подкоманд для ca65.exe
а также ld65.exe
, Это ассемблер и компоновщик. Также обратите внимание, что я ссылаюсь на файл конфигурации в моем компоновщике. Вы увидите это в -C "mon.cfg"
, Этот конфигурационный файл сообщает ассемблеру / компоновщику, какой у меня тип компьютера, где отображается память и т. Д. Я считаю, что в ca65 уже есть ссылки на популярные компьютеры, такие как C64. Таким образом, вам может не понадобиться этот конфигурационный файл в процессе компоновки.
Однако, для справки, вот файл конфигурации, который я использую:
mon.cfg
MEMORY {
ZP: start = $0000, size = $0100, type = rw;
RAM: start = $0000, size = $4000, fill = no, type = rw;
ROM: start = $8000, size = $8000, fill = yes, file = %O;
VEC: start = $FFFA, size = $0006, fill = no, type = ro;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
CODE: load = ROM, type = ro;
}
Опять же, вам может даже не понадобиться файл конфигурации. Ознакомьтесь с документацией по использованию директив C64. Но, к вашему сведению, разработанный мной 6502 компьютер имеет 16 КБ ОЗУ и 32 КБ ПЗУ. Вы можете увидеть, что отражено в файле конфигурации.
Удачи!
Полная команда для компоновщика:
ld65 --lib c64.lib -C c64-asm.cfg -o basic.prg basic1.o
Это создает файл basic.prg с 2-байтовым заголовком адреса загрузки.