XA or CA65 ?

Here you can ask questions or provide insights about how to use efficiently 6502 assembly code on the Oric.

Wich assembler do you use: XA or CA65 ?

XA
4
57%
CA65
3
43%
 
Total votes: 7

User avatar
Symoon
Archivist
Posts: 2307
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

XA or CA65 ?

Post by Symoon »

Hi,

I plan trying a bigger ASM project than what I did before, which could require the writing of actual ASM sources (and not just commented opcodes as I've been doing so far).

But I read some are using "XA" and other "CA65". Consider I know NOTHING about what those beasts are, but I want to use the one that is used by most Oric coders. Also, I'm not willing to have to learn two different things and evaluate them before chosing the right one, or my project won't start before 2035).

So the question is simple: which one is used by the majority? ;)
Thanks!
PS: you can vote for both if you're using both.
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: XA or CA65 ?

Post by xahmol »

To clarify: I choose CA65 not because I think it is better. I us3 it mainly because I prefer the C compiler of CC65 way over the OSDK one, and mixing assembler with CC65 C code is way easier to do with assembly code in CA65.
User avatar
Symoon
Archivist
Posts: 2307
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: XA or CA65 ?

Post by Symoon »

xahmol wrote: Mon Jul 18, 2022 2:08 pm To clarify: I choose CA65 not because I think it is better. I us3 it mainly because I prefer the C compiler of CC65 way over the OSDK one, and mixing assembler with CC65 C code is way easier to do with assembly code in CA65.
Thanks!
Do you mean that if you were programming 100% in assembler, you might have chosen XA instead - or do you have no idea of what your choice would be in this very context?
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: XA or CA65 ?

Post by xahmol »

Symoon wrote: Mon Jul 18, 2022 3:25 pm Thanks!
Do you mean that if you were programming 100% in assembler, you might have chosen XA instead - or do you have no idea of what your choice would be in this very context?
The latter. Did most of my programming on Commodores, so if I would have started pure assembler probably had started with KickAss or ACME there. On Oric, I probably would have gone for XA65 as that is in OSDK.

But I also think that for my needs really both are more than up to the task. My only nuisance is that I now have to convert XA65 sources of others to CA65 format because I think most here use XA65. Luckily I now more and more know how to do that and it is not difficult. Of course opp codes are just the same, so it is mainly placing a lot of : after labels as XA65 has labels without them and CA65 with.

But think DBug can give you all the advantages of XA65 in quite some detail 😉 think his reasons are the main reason why OSDK does not use CC65 (not blaming him in any way by the way, converting all your sources is a pain and as he codes mostly on assembler only he has no gain from CC65)
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: XA or CA65 ?

Post by xahmol »

Oh, by the way: that I code on both Commodores as Oric is also a HUGE reason why I prefer CC65 and CA65. Code is portable to other CC65 projects to a large extent even between Oric and Commodore (apart from memory locations and kernal calls of course).
User avatar
iss
Wing Commander
Posts: 1641
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: XA or CA65 ?

Post by iss »

Recently I was thinking to post almost same topic ("XA vs. CA65") but with different aim: to show practical hints, side effects, details and bugs which I found by "the hard way" and collected during last years. Hoping that this will help and spare lot of someone's time. So I'll do it asap!

@Symoon: On your question:
- in regard of assembler coding main difference is that CA65 supports real macros (I mean you can write whole program inside your program using macros with if/else and for loops) while XA uses macros in form of preprocessor directives (#define, #if/#else etc) which act like simple string replacement. Both can make the source nice and more readable saving lot copy/paste of duplicate parts of the program. Both are useful. Both can give you pain hiding difficult to find bugs. CA65's macros are more complex!

- mixing C and ASM is not problem at all (maybe sometimes not easy but definitely works and @xahmol: no need manual work :idea:) but this is out of scope in this topic.

So, I voted for both because ... I use them both but I will honestly suggest you XA - at-least I know 3 active forum members who will always help you (for me I promise!).
User avatar
Symoon
Archivist
Posts: 2307
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: XA or CA65 ?

Post by Symoon »

Thanks for the feedback guys!
Precisely I don't have much knowledge on what macros are, and so on. That is typically the kind of thing I will have to learn/understand with ASM.
This is why I hope I can make the right choice at start: learning a new language right, but not willing to start by dealing with local subtleties of North 6502 ASM and South 6502 ASM ;)
User avatar
Dbug
Site Admin
Posts: 4444
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: XA or CA65 ?

Post by Dbug »

Macros are not specifically assembler related, it's just basically some "text expansion" which help alleviate typing the same stuff again and again.
They are also often use to easily enable or disable some bits of code depending of the compilation options using conditional assembly.

Typical examples would be:
- Have some diagnostic messages and test code in test versions, which you don't want to be present in the final version.
- Have a game in multiple languages in the same source code, and from the same source code generate different binaries for various countries, each with their own language.
- Publish demo versions of a game, where some features are not enabled.

Regarding the various dialects, there are two very different things:
- The actual assembler syntax used for keywords, hex, immediate or absolute values, etc...
- The "meta commands" like things to reserve bytes, change the address of the program counter, macros and special operations, etc...

Assembler syntax on the 6502 are mostly identical these days, but back in the days some used different convention to indicate what was decimal, hexadecimal, immediate or address, now that's mostly fixed.

Meta commands on the other day, are all very different, and that's typically where CA65 and XA differ, they use the same assembler opcode syntax, but things like defining labels, sections, bla bla bla, are very different.
User avatar
Symoon
Archivist
Posts: 2307
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: XA or CA65 ?

Post by Symoon »

Thanks for the explanation!
Dbug wrote: Tue Jul 19, 2022 12:08 pm Assembler syntax on the 6502 are mostly identical these days, but back in the days some used different convention to indicate what was decimal, hexadecimal, immediate or address, now that's mostly fixed.

Meta commands on the other day, are all very different, and that's typically where CA65 and XA differ, they use the same assembler opcode syntax, but things like defining labels, sections, bla bla bla, are very different.
That is typically what I have to learn. Books are all about the instructions, but not about the syntax, and so far when I try reading a source code, it's still alien language to me with things like .dsb, .byt, .equ and so on. It's certainly nothing when you're used to it, but out of nowhere when you're not ;)
I suppose books don't tell much about it because it can be specific to each assembler? Lance Leventhal's book seems to have a few pages about it, I'll begin with that but I suspect I will have to switch to XA or CA65 documentation quite fast, hoping it is not written just for 6502 wizards ;)
User avatar
Dbug
Site Admin
Posts: 4444
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: XA or CA65 ?

Post by Dbug »

Basically all in all, there are a few categories:

1/ Data definition
These ".dsb", ".byt", etc... are relatively common across all assemblers on all processors, there are only a few variants to know.

For XA you can find them in the documentation.

I generally use ".dsb" to reserve some non initialized space which will be filled later, while ".byt" and ".word" are the actual equivalent of the DATA instruction in BASIC, the first one write a byte and the second a two bytes value. I use that for tables, like

Code: Select all

ModuloSix  .byt 0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5
2/ Defines/equates
".equ" is just a way to define constant values, like the value of mathematical constants, giving name to things to make it more practical (like COLOR_RED instead of "1"), etc...

Most assemblers have their own way of doing it, but ultimately it just means "associating a name to a value".

I personally tend to use #define because that allows me to share these constants between the C and assembler modules, and that's actually the thing I prefer in XA over many other assemblers: It does support the C style pre-processor, so #define, #if, etc... can easily be shared between C and assembler, which I tend to use a lot for things like the Floppy Builder API code

Code: Select all

//
// FloppyBuilder/Loader system
// Compatible with both C and Assembler modules
//
#include "floppy_description.h"

#ifdef ASSEMBLER    // 6502 Assembler API
#define LoadFileAt(fileIndex,address)          lda #fileIndex:sta _LoaderApiEntryIndex:lda #<address:sta _LoaderApiAddressLow:lda #>address:sta _LoaderApiAddressHigh:jsr _LoadApiLoadFileFromDirectory
#define InitializeFileAt(fileIndex,address)    lda #fileIndex:sta _LoaderApiEntryIndex:lda #<address:sta _LoaderApiAddressLow:lda #>address:sta _LoaderApiAddressHigh:jsr _LoadApiInitializeFileFromDirectory

#else               // C Compiler API
extern unsigned char LoaderApiEntryIndex;
extern unsigned char LoaderApiAddressLow;
extern unsigned char LoaderApiAddressHigh;
extern void* LoaderApiAddress;

#define LoadFileAt(fileIndex,address)          LoaderApiEntryIndex=fileIndex;LoaderApiAddress=(void*)address;LoadApiLoadFileFromDirectory();
#define InitializeFileAt(fileIndex,address)    LoaderApiEntryIndex=fileIndex;LoaderApiAddress=(void*)address;LoadApiInitializeFileFromDirectory();

#endif
3/ Sections
Most assemblers and linkers have the concept of sections, which are often mapped on the operating system features. Like for example, a typical program will have "code" but also "data" and "variables". Instead of having all that in one big blob of a file, they are spread over multiple "sections", which can be used to optimized things.

Typically for example to avoid crashes and bugs, Windows and Linux will flag the code of the program as "non writable" to avoid hacks and corruption, and on embedded systems you have "data" as well as "read only data", to separate what can be modified from what can be put in ROM for example.

Then there's the "variables" section, which is general just a size information: No need to save the zeroes in the file, instead all we need is to know where it starts and how long it is, then you can clear up

In practice on the ORIC (and Atari ST) they are called "zero" (zero page), "text" (code), "data" and "bss" (block storage section).

Each of these sections have their own internal address counter (accessed by "*" on most assemblers), and if you have multiple "zero" or "text" they are all grouped together.

A simple program in XA would be like that:

Code: Select all

 .zero

* = $50                              ; Zero page variables start in $50

zp_my_variable  .dsb 1      ; reserves one byte
zp_my_pointer   .dsb 2      ; reserves two bytes

 .text

*= $500                              ; Program assembled at address $500

main
  lda some_value                ; Reads 42
  sta zp_my_variable          ; Write it to zero page

  lda #<some_value            ; Reads low byte of address
  sta zp_my_pointer+0        ; Write it to zero page
  lda #>some_value            ; Reads highbyte of address
  sta zp_my_pointer+1        ; Write it to zero page

  ldy #0
  lda (zp_my_pointer),y
  sta overlay_array             ; Write 42 to the first byte of the array

 .data

some_value  .byt 42

  .bss

*=$c000                            ; Map BSS to overlay ram

overlay_array  .dsb 256    ; Table of 256 bytes not saved in executable
The strength of these sections don't appear when you only have one source file, but when you have many, you can have each one have it's own clearly delimitated area for variables in bss and zero page, and the final program has these sections merged together, it's very practical.

CA65 goes way beyond that because it has support for many more sections, to accommodate things like the complicated banking system on the Commodore 64 or some consoles but the basic assembler syntax itself is the same as in XA, with # for immediate values, $ for hexadecimal, same way of using parenthesis to define zero page addressing pointers, etc...
User avatar
Symoon
Archivist
Posts: 2307
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: XA or CA65 ?

Post by Symoon »

Thanks a lot, that's helpful!
User avatar
Chema
Game master
Posts: 3014
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: XA or CA65 ?

Post by Chema »

I have used the old frasm assembler included in the lcc65 package and switched to XA with the appearance of OSDK.

I am quite fine with how XA does things by using preprocessor directives. Yeah, there are some quirks and bugs, but you can have headers which are shared between C and asm and everything seems natural to me.

I particularly love the way it handles labels and blocks. Labels do not need the colon ':' and are global or local depending only if they are inside a block of not. Blocks are defined with '.(' and '.)' (yeah, I'd love they had used '{}') and, most importantly, can be nested. But not only that, you can precede a label that's defined inside a block with '+' to make it global, or with '&' to make it 'one-level-up', or reuse it with a '-'.

So I got used to create code as this:

Code: Select all

PurgeLocalScripts
.(
    ldx #MAX_THREADS-1
loop
    ; If the thread is not empty
    lda thread_state,x
    beq skip		; Empty is zero
    ; And it contains a local script (or code of local object)
    lda thread_script_id,x
    cmp #RESOURCE_LOCALS_START
    bcc skip
    ; Purge the script (old version just set the state as EMPTY)
    jsr PurgeScript
skip
    dex
    bpl loop
 
    rts
.)	
Always inside a block, common local labels are always named loop, skip, checkzero, ...

Whenever I want to have two entry points for a function it is easy:

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Jump instructions (relative)
; Two versions: inconditional and conditional
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
scJumpRel
.(
    jsr scriptEvaluateNext
+scJump_ex
    ora #00	; Flags are lost
    bmi neg
    ldy #0
    beq pos
neg
    ldy #$ff
pos	
    ldx _CurrentThread
    clc
    adc thread_offset_lo,x
    sta thread_offset_lo,x
    tya
    adc thread_offset_hi,x
    sta thread_offset_hi,x
    rts
.)
In this case, it would have been possible to have split them, but you get the idea. And you can have local symbols for both.

And I usually have a lot of #ifdef-#else sections around.

If there is one thing I miss a lot is a way to create static tables in assembly time.
User avatar
Dbug
Site Admin
Posts: 4444
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: XA or CA65 ?

Post by Dbug »

Indeed XA has a few weaknesses, typically it does not support things like "repeat" blocks which can be used on the Atari ST Devpac to generate complicated structures at runtime, like the tables to access scanlines, etc...

It also does not have "incbin", and it would be nice if it could understand hexadecimal values in the format used by the C compilers (0xFF instead of $FF) which would make it 100% compatible with C for the includes.
User avatar
Symoon
Archivist
Posts: 2307
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: XA or CA65 ?

Post by Symoon »

XA is now the (very short) majority. From what I've understood, it seems a bit simplier to start, and it's in the OSDK so I guess I'll have a go with it.
Thanks to all for your help, comments, votes, ... And I suppose, see you soon with stupid problems and a desperate Symoon ;)
User avatar
Dom
Flying Officer
Posts: 141
Joined: Sun Nov 25, 2012 7:00 pm

Re: XA or CA65 ?

Post by Dom »

Hi,
From 1984 to the mid-2010s, I have used the "monitor AS1" from Loriciels :lol: to produce small (and medium) routines for games like "Meurtres en série" (MES) (KIS in English for Killings in Sark) Or "Meurtres sur l'atlantique" (Murders on the Atlantic)

From the mid-2010s I decided to "modernize" my knoledge in ASM coding and without hesitation I choose the OSDK as obvious. Of course, without knowing which cross assembler was used and without knowing an alternative existed :)

After some time of reflexion to try to understand the reasons of such a quik choice, what comes to mind is :

- Reports of old coding parties and difficulties in exchange code between Dbug, jede and Twilighte, because Dbug and Jede used OSDK and Twiligte used another cross assembler.
- Reports of later coding parties with things getting better because Twilighte changed his mind and adopted OSDK
- OSDK exists and is documented well enough for a beginner to start a project
- The OSDK package is quite complete and usefull for ASM and BASIC code ,for Pictures, for music ...

After several years of using the OSDK, what can I say?

- Getting Started with XA is quite easy for a beginner (thanks to XA documentation in the OSDK package)
- I probably use only 40 to 50% of XA possibilities.
- At this time my knowledge seems sufficient to code my projects .
- I am far to be a high level coder :-)

Now I Wonder If this question of choice XA or CC65 is really important for a beginner ? (I hope no )
Or if this choice is really important only for high level coders, several years after having been a bebinner :-) ?

Subsidiary question : Once you are a good ASM coder, is it difficult to switch from XA to CC65 or vice-versa ?
Post Reply