2 Beginner questions about assembly programming using CC65

Chat about anything CX16 related that doesn't fit elsewhere
JvH
Posts: 10
Joined: Wed Feb 03, 2021 6:19 pm

2 Beginner questions about assembly programming using CC65

Post by JvH »


Hello!

During the last couple of days I've been converting a CBM prg Studio ML project (target: Commodore 64) to CX16. I'm using the cc65 suite to assemble my code.

At this moment there are 2 things about cc65 that I don't really understand.

1) The CONDES section in cx16-asm.cfg

From what I understand, this is mostly meant for C development. Each module can 'export' pointers to their constructor and destructor code, so that this code is called before/after main() is executed. I am, however, only using assembly. So my questions are:

* What purpose does it serve when you're using only assembly? It's in cx16-asm.cfg after all, so it must be there for a reason right?

* The constructor entry refers to a segment (ONCE) that's not even present in the configuration. Is this created on-the-fly? If so, in which memory segment does it get added?

* What is the interruptor entry for?

2) Working with multiple files

In hopes of increasing readability, I split my project into multiple files. I use .include to refer to other files, which just inserts the file contents at the position of the .include. I'm really not sure if this is the way to go. Yes, I don't have to .import and  .export and still have access to all identifiers in my code. But the downside is that you really have to be careful about including files twice or including them in the wrong order.

Are there some developers with experience in cc65 who can give me some hints and tips on managing multi-file cc65 projects?

Thanks in advance for your replies.

Elektron72
Posts: 137
Joined: Tue Jun 30, 2020 3:47 pm

2 Beginner questions about assembly programming using CC65

Post by Elektron72 »



  1. A lot of the stuff in the cc65 configuration files isn't necessary for assembly. While this extra section might enable some advanced features, I have never used any of them.


  2. I use multiple separately assembled files, which are linked together to build the program. While this does require me to import and export symbols, I am thinking of writing something similar to a C header file for future projects.


JvH
Posts: 10
Joined: Wed Feb 03, 2021 6:19 pm

2 Beginner questions about assembly programming using CC65

Post by JvH »


Hi Elektron72,

Thanks for your very quick reply!


Quote




A lot of the stuff in the cc65 configuration files isn't necessary for assembly. While this extra section might enable some advanced features, I have never used any of them.



Indeed, I don't think I'll need this anytime soon. Still curious why they included it in a config that is specific to assembly. Maybe when you assemble your code into a module and link that into a C project.


Quote




I use multiple separately assembled files, which are linked together to build the program. While this does require me to import and export symbols, I am thinking of writing something similar to a C header file for future projects.



Could you explain to me how that works? Is it a matter of exporting the symbols you're going to need externally, assembling your code into a .o file (without the BASIC header of course) and then including that .o file when calling cl65?

User avatar
StephenHorn
Posts: 565
Joined: Tue Apr 28, 2020 12:00 am
Contact:

2 Beginner questions about assembly programming using CC65

Post by StephenHorn »



2 hours ago, JvH said:




Could you explain to me how that works? Is it a matter of exporting the symbols you're going to need externally, assembling your code into a .o file (without the BASIC header of course) and then including that .o file when calling cl65?



That's exactly it, yes.


  • To declare a symbol that needs to be exported, your use the `.export` statement.


  • And similarly, to declare a symbol that needs to be imported from another module, you use the `.import` statement.


  • ca65 also has the `.global` statement, which I find extremely convenient because it changes meaning based on whether or not a symbol is defined elsewhere within a module.


So, for instance, I have a "math.inc" file that contains a bunch of .global statements for my math procedures, like so:

.global math_init
.global cos_8
.global sin_8
.global mul_8

These procedures are all implemented in "math.asm", so I make sure that math.asm includes that inc file, and I make sure any other source file that needs to use my math procedures also includes math.inc, such as my "splash.asm" that does my little demo splash screen intro.

By including math.inc into math.asm, ca65 will see the symbols defined and interpret the globals to mean that those symbols need to be exported. By including math.inc into splash.asm, ca65 will see that the symbols were never defined and interpret the globals to mean that those symbols need to be imported.

Then I compile the .asm files into .o files individually with ca65, then link them together into a final executable with cl65:

ca65 --cpu 65C02 math.asm -o math.o
ca65 --cpu 65C02 splash.asm -o splash.o
cl65 --target cx16 math.o math.o -o SPLASH.PRG

See also: https://www.cc65.org/doc/ca65-11.html

Developer for Box16, the other X16 emulator. (Box16 on GitHub)
I also accept pull requests for x16emu, the official X16 emulator. (x16-emulator on GitHub)
JvH
Posts: 10
Joined: Wed Feb 03, 2021 6:19 pm

2 Beginner questions about assembly programming using CC65

Post by JvH »


Hello Stephen, thanks for your answer.

Let me check if I understand this correctly.

* You put all global symbols from math.asm in a separate math.inc file, and you include that file (with .include) in math.asm

* Assembling math.asm yields math.o, which contains the ML code + the used symbols

* In splash.asm you .include math.inc, but when linking you refer to math.o

Am I correct?

Another question that comes to mind:

Suppose you have a math.asm with cos, sin and tan functions. Let's assume, for the sake of argument, that those functions don't share any code.

Now if you include math.inc in your program only to use the sine function, I assume math.asm will still be added to the prg file in its entirety. Is that correct?

EDIT: now that I come to think of it, I suppose that is what .ifref could be used for...

EDIT2: oh right, that's exactly what the documentation says ?

User avatar
StephenHorn
Posts: 565
Joined: Tue Apr 28, 2020 12:00 am
Contact:

2 Beginner questions about assembly programming using CC65

Post by StephenHorn »



1 hour ago, JvH said:




Hello Stephen, thanks for your answer.



Let me check if I understand this correctly.

* You put all global symbols from math.asm in a separate math.inc file, and you include that file (with .include) in math.asm

* Assembling math.asm yields math.o, which contains the ML code + the used symbols

* In splash.asm you .include math.inc, but when linking you refer to math.o

Am I correct?



Another question that comes to mind:

Suppose you have a math.asm with cos, sin and tan functions. Let's assume, for the sake of argument, that those functions don't share any code.

Now if you include math.inc in your program only to use the sine function, I assume math.asm will still be added to the prg file in its entirety. Is that correct?



EDIT: now that I come to think of it, I suppose that is what .ifref could be used for...

EDIT2: oh right, that's exactly what the documentation says ?



For the most part, this is all correct.

Technically, assembling math.asm yields math.o, which contains an intermediate representation of the ML + used symbols. This might be an academic difference, but I suppose the important thing to note is that it isn't necessarily the final machine language, even with annotations, because the assembler won't necessarily know a bunch of important details, such as the values of external symbols, or even the final location of the code that's been assembled.

All of that information is reconciled by the linker, which is given all of the necessary modules (the .o files), in order to figure out all the symbols and organize them into their final locations.

Developer for Box16, the other X16 emulator. (Box16 on GitHub)
I also accept pull requests for x16emu, the official X16 emulator. (x16-emulator on GitHub)
JvH
Posts: 10
Joined: Wed Feb 03, 2021 6:19 pm

2 Beginner questions about assembly programming using CC65

Post by JvH »


Ah right my wording was a bit too simplistic.

Thanks for your answer. With this knowledge I can begin restructuring and tidying up the littte game I'm trying to put together.

JvH
Posts: 10
Joined: Wed Feb 03, 2021 6:19 pm

2 Beginner questions about assembly programming using CC65

Post by JvH »


I'm trying to create an object file containing VERA-related subroutines, but I can't get it working.

I've got vera.inc, which contains (among other things):

.global clearScreen

I have vera.asm:

.include "vera.inc"

...

.ifref clearScreen

.proc clearScreen

...

.endproc

.endif



In my main program I have:

.include "vera.inc"

...

jsr clearScreen



I get the error:

"Unresolved external 'clearScreen' referenced in:

  program.asm(12)

ld65: Error: 1 unresolved external(s) found - cannot create output file"

If I remove the .ifref ... .endif lines it works, but I'd really like to include only the stuff from vera.o that I actually need. What am I doing wrong?

User avatar
JimmyDansbo
Posts: 476
Joined: Sun Apr 26, 2020 8:10 pm
Location: Denmark
Contact:

2 Beginner questions about assembly programming using CC65

Post by JimmyDansbo »


If I understand the documentation correctly (https://www.cc65.org/doc/ca65-11.html#ss11.58), .ifref only returns true if something has referenced the name before it reaches the .ifref 

In your case I am guessing you are including vera.inc in the beginning of vera.asm hence clearScreen has not been referenced yet when the compiler goes through the vera.inc source.

Visit my Github repo
or my personal site with CX16/C64/6502 related information.
Feel free to contact me regarding any of my projects or even about meeting up somewhere near Denmark
JvH
Posts: 10
Joined: Wed Feb 03, 2021 6:19 pm

2 Beginner questions about assembly programming using CC65

Post by JvH »


Indeed, that's what the documentation says. So I've already tried including vera.inc at the end of my main program's asm file. Still, it gives the same error. I also tried switching vera.o and program.asm in the call to cl65, but that didn't help either.

Post Reply