ca65 assembler and ld65 linker

那年仲夏 提交于 2019-12-10 18:49:05

问题


I'm beginning to use then ca65 assembler and ld65 linker on WIndows to create binary code for Commodore C64 computer, running on VICE emulator.

I write this small "hello world" source on file "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

I can assemble with the command:

ca65 -t c64 basic2.s

And generate "basic2.o"

I read the documentation of the linker ld65 and it's confusing

I have tried unsuccessfully:

1-With command

ld65 basic2.o

error is:

ld65: Error: Memory configuration missing

2-With command

ld65 -C c64-asm.cfg basic2.o

error is:

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

Thanks


回答1:


The documentation is a bit scattered, but it's all there if you look hard enough.

When you specify a config it determines the format of the output object. And in c64-asm.cfg is:

__LOADADDR__: type = import;

This config expects something to export LOADADDR so it can build the PRG header. If you link with c64.lib (etc) then that exports it (hardcoded to $801). Otherwise you need to supply it yourself.

One way is on the command line with --start-addr as Laurent H. and the docs suggest, but that's fiddly. Instead you can get your assembly language source to export it. I don't know CC65 well, but:

.org    $0801
.export LOADADDR = *

Also, you can build in one line with:

cl65.exe -o basic2.prg -t c64 -C c64-asm.cfg basic2.s



回答2:


The full command for linker is:

ld65 --lib c64.lib -C c64-asm.cfg -o basic.prg basic1.o   

This generate the basic.prg file with the 2 byte load address header.




回答3:


The following is how I have my build environment setup. I'm coding for a custom 6502 SBC that I designed (not a Commodore 64) but the technique is very similar. I have a small program called "mon.asm" (for monitor). Also, in my project directory, I have a couple working directories called tmp and dist. Tmp is where *.o (object) files and other temporary working files go. The dist folder is where my finished binary file goes (the file I actually burn to EEPROM).

First, I setup a make.cmd job to setup environment variable, assemble, link, etc. This job cleans out my folders and builds/links the binary file.

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"

Notice that file has a couple sub-commands for ca65.exe and ld65.exe. That's the assembler and linker. Also notice I reference a config file in my linker. You'll see that in the -C "mon.cfg". That config file tells the assembler/linker what type of computer I have, where the memories are mapped, etc. I believe ca65 already has built in references for popular computers like the C64. So you may not need that config file in your link process.

However, for reference, here is the config file I am using:

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;
}

Again, you may not even need the config file. Check the documentation on using the C64 directives. But for your information, the 6502 computer I designed has 16K of RAM and 32K of ROM. You can see that reflected in the config file.

Good luck!



来源:https://stackoverflow.com/questions/51790718/ca65-assembler-and-ld65-linker

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!