cc65 working group

nattil

New Member
Oct 14, 2019
11
1
3
Hey all,

I would love to join up with any existing efforts to make developing in cc65 for cx16 easier. For now, I was thinking we could at least get a Discord channel going? Would anyone be interested?
 

codewar65

New Member
Sep 25, 2019
26
13
3
A cc65 group would be great.

I'm having issues getting the linker to work. Doing straight assembler. ca65 creates a object .o file but that is far as I get. Getting an error:

ld65: Error: Input file 'cx16.lib' not found

and I can't find any such lib file, nor why I'd need one being I'm writing in 6502.

I'll tinker around with later this week. My brain is tired looking at this. haha.

This is the first 6502 code I've written in 35 years, and excited to get my feet wet again.

Maybe cc65 is not the toolset I'm looking for. I am familiar with it's 6502 syntax ( .ORG vrs * = ) and looking for a simple 6502 macro assembler that uses it's syntax. [I may play around with C in the future, but I am under the impression that C (Pascal, etc) are best suited for 16+ bit CISC architecture.]
 
Last edited:

nattil

New Member
Oct 14, 2019
11
1
3
A cc65 group would be great.

I'm having issues getting the linker to work. Doing straight assembler. ca65 creates a object .o file but that is far as I get. Getting an error:

ld65: Error: Input file 'cx16.lib' not found

and I can't find any such lib file, nor why I'd need one being I'm writing in 6502.

I'll tinker around with later this week. My brain is tired looking at this. haha.

This is the first 6502 code I've written in 35 years, and excited to get my feet wet again.

Maybe cc65 is not the toolset I'm looking for. I am familiar with it's 6502 syntax ( .ORG vrs * = ) and looking for a simple 6502 macro assembler that uses it's syntax. [I may play around with C in the future, but I am under the impression that C (Pascal, etc) are best suited for 16+ bit CISC architecture.]
Yeah sounds like you want the asm toolchain. C isn't going to be the best way to write code for the platform in terms of performance, but for me at least it will make delivering a working game much easier.
 
  • Like
Reactions: codewar65

GregZone

Member
Sep 29, 2019
32
20
8
ld65: Error: Input file 'cx16.lib' not found

and I can't find any such lib file, nor why I'd need one being I'm writing in 6502.
If it's any help, the cx16.lib file is indeed in the cc65 lib subfolder.

At least on V2.18, which supports the -t cx16 switch.

Is it possible you are using a release version prior to the cx16 target system support being added (with some cx16 targetted source)?

ps. I haven't written 6502 machine code in at least 30 years either. :)
 
  • Like
Reactions: codewar65

codewar65

New Member
Sep 25, 2019
26
13
3
If it's any help, the cx16.lib file is indeed in the cc65 lib subfolder.

At least on V2.18, which supports the -t cx16 switch.

Is it possible you are using a release version prior to the cx16 target system support being added (with some cx16 targetted source)?

ps. I haven't written 6502 machine code in at least 30 years either. :)
I have a libsrc directory, no lib. I've built the latest cc65 using Visual Studio 2019 using the project files. It was a no brainer. Do I need to build the lib files separately from libsrc? and HOW-TO?

ps: I'm finding coding 6502 is like riding a bike. I can see a opcode with operands and know how many bytes it is. I have forgotten how many clocks each take though. I will have to re-create my old cheat-sheet. lol
 

GregZone

Member
Sep 29, 2019
32
20
8
I have a libsrc directory, no lib. I've built the latest cc65 using Visual Studio 2019 using the project files. It was a no brainer. Do I need to build the lib files separately from libsrc? and HOW-TO?

ps: I'm finding coding 6502 is like riding a bike. I can see a opcode with operands and know how many bytes it is. I have forgotten how many clocks each take though. I will have to re-create my old cheat-sheet. lol
Ahh, I suspect you'd need to also compile the libsrc folder. I haven't looked into this, but I see there is a Makefile.

But... Instead of compiling the cc65 source, I've just been using the latest cc65 windows snapshot:

The current snapshot version is: V2.18 - Git f3d898d

Hope this helps.

ps. I always remember 6502 clock cycle counts being a pain. eg. When you have to add extra cycles for page boundaries.
Overall, I always got frustrated with 6502 machine code, compared to the 6800 & 6809 tidiness that I was previously familiar with (at the time).
 
  • Like
Reactions: codewar65

codewar65

New Member
Sep 25, 2019
26
13
3
A future project, maybe, for a way for VS users to build libsrc and other needed files. Unfortunately, MS Visual Studio is inherently MAKE ignorant. haha

I'll give your build a spin. Thanks Greg!
 

LRFLEW

New Member
Sep 23, 2019
17
4
3
I was thinking we could at least get a Discord channel going?
I mean, I think we should have a Commander X16 Discord server, and we can dedicate a chat room to cc65 related discussions.

As I commented somewhere else, I do want to make a floating point arithmetic library for cc65 that utilizes the functions from the BASIC ROM. Right now, there's no reliable way to call into it (i.e. any changes to the ROM project could easily break it), but while I wait for an "API" for it, I could start it with hard-coded addresses (when I find time that is).
 

nattil

New Member
Oct 14, 2019
11
1
3
I mean, I think we should have a Commander X16 Discord server, and we can dedicate a chat room to cc65 related discussions.
Agreed, but building that seems like an overreach on my part, though I'd love to join an official one. I'm just selfishly looking to find other cc65 developers :)
 

Schol-R-LEA

New Member
Sep 20, 2019
17
10
3
The cc65 package has a separate assembler (ca65) and linker (ld65), though apparently, the real intent for a simple program is to use the compiler/linker combined driver, cl65. Also, there are different settings and configuration files corresponding to different 6502 platforms (Apple II, Apple IIGS, Pet, VIC20, C64, C128, NES, etc.), including one for the Commander x16. You supposedly can use the default -t cx16 configuration with the cl65 driver, but so far it always gives me an error - I've ended up using the explicit configuration file option instead, like in my example PETSCII print program:

Code:
ca65 petscii-simple.asm -t cx16 -o petscii-simple.o -l petscii-simple.lst
Code:
cl65 petscii-simple.o -C cx16-asm.cfg -o petscii-simple.prg
However, whenever I try to use the linker directly, I get an error stating that _LOADADDR_ can't be resolved. I have also run into a problem when trying to link a second object file into a program, and I'll post more about that once I have a suitable text example.
 

GregZone

Member
Sep 29, 2019
32
20
8
You supposedly can use the default -t cx16 configuration with the cl65 driver, but so far it always gives me an error - I've ended up using the explicit configuration file option instead, like in my example PETSCII print program:
Not sure if this helps, but the cx16-asm.cfg documentation states:
This configuration is made for Assembly programmers who don't need a special setup. The default start address is $0801. It can be changed with the linker command-line option --start-addr or -S. All standard segments, with the exception of ZEROPAGE, are written to the output file; and, a two-byte load address is prepended.
To use that config. file, assemble with -t cx16, and link with -C cx16-asm.cfg. The former will make sure that the correct character translations are in effect, while the latter supplies the actual config. When using cl65, use both command-line options.
ie. Specifically note: "When using cl65, use both command-line options."

So this would translate to this single combined cl65 compile / link command-line (using your code example):
Code:
cl65 petscii-simple.asm -t cx16 -C cx16-asm.cfg -o petscii-simple.prg
Apologies if I've misunderstood your post.
 

Schol-R-LEA

New Member
Sep 20, 2019
17
10
3
Not sure if this helps, but the cx16-asm.cfg documentation states:


ie. Specifically note: "When using cl65, use both command-line options."

So this would translate to this single combined cl65 compile / link command-line (using your code example):
Code:
cl65 petscii-simple.asm -t cx16 -C cx16-asm.cfg -o petscii-simple.prg
Apologies if I've misunderstood your post.
OK, that helps. I'm now able to assemble and link a pair of programs, but the code doesn't actually run, which makes me think it is a memory layout issue - some aspect of setting up the program which I haven't understood yet.

For test purposes, I created a modified version of the PETSCII program with the actual print loop in a separate function, but still part of the same source file and assembly run:

Code:
.include "../../src/sys.inc"
   
; macro to set the origin and executable header
CX16_HEADER

start:
    ;; call macro to set ROM bank to Kernal ROM
     set_rombank RB::BASIC
    jsr petscii
    rts


.proc petscii
    lda CR
    jsr BASOUT
    lda #$40
loop:   
    jsr BASOUT   
    adc #1
    cmp #$7F
    bne loop
exit:
    rts
.endproc
... where BASOUT is the BASIC ROM character output routine, and CX16_HEADER and set_rombank are helper macros for the program prefix and selecting the ROM bank.
Code:
;;; common constants
; Carriage Return and Line Feed
CR = $0D
LF = $0A

;;; ROM Banks
.enum RB
    Kernal
    Keyboard
    CBDOS  
    GEOS
    BASIC
.endenum

.scope IO
    .scope Audio
    Base        = $9F00
    .endscope
    ;;
    .scope VERA
    Base        = $9F20
    .endscope
    ;;
    .scope VIA
        Ctrl0_Base  = $9F60
    .enum Banks
            Mem = $9F60   
            ROM   
    .endenum
    Ctrl1_Base  = $9F70
    .endscope
    ;;
    .scope RTC
    Base        = $9F80
    .endscope
.endscope

.macro set_rombank bank
    lda bank
    sta IO::VIA::Banks::ROM  
.endmacro

This works correctly, so the problem isn't with the function itself. However, when I place the petscii routine in a separate file and .import the routine before the start: label,

Code:
.include "../../src/sys.inc"
.import petscii

; macro to set the origin and executable header
CX16_HEADER

start:
    ;; call macro to set ROM bank to Kernal ROM
     set_rombank RB::BASIC
    jsr petscii
    rts
Code:
.include "../../src/sys.inc"

.export petscii
   
.proc petscii
    lda CR
    jsr BASOUT
    lda #$40
loop:   
    jsr BASOUT   
    adc #1
    cmp #$7F
    bne loop
exit:
    rts
.endproc
both files assemble, and seem to link correctly,
Code:
$ ca65 petscii-print-separate.asm -t cx16 -o petscii-print-separate.o
$ ca65 petscii-separate.asm -t cx16 -o petscii-separate.o
$ cl65 petscii-separate.o  -t cx16 -C cx16-asm.cfg --lib petscii-print-separate.o  -o petscii-separate.prg
but when run, it gives the following error message:
Code:
?SYNTAX ERROR IN 53792
Now, as I said, I expect that this is due to issues with how the linker is laying the code out in the PRG file. I've tried to move the .import statement to a point after the main routine, on the off-chance that it was affecting how the link build ran, but this didn't change the results (I didn't really expect it to).
 

GregZone

Member
Sep 29, 2019
32
20
8
OK, that helps. I'm now able to assemble and link a pair of programs, but the code doesn't actually run, which makes me think it is a memory layout issue - some aspect of setting up the program which I haven't understood yet.

For test purposes, I created a modified version of the PETSCII program with the actual print loop in a separate function, but still part of the same source file and assembly run:
...
I just did my own little test of spliting your original example (to similarly seperate out the petscii print proc, into a seperate .include file), and I had no issues or errors. Compiled and ran perfectly. :)

This was using the following compile & link command (using your naming convention):
Code:
cl65 petscii-separate.asm petscii-print-separate.asm -t cx16 -C cx16-asm.cfg -o petscii-seperate.prg
I'm not sure why you are using ca65 to first compile, then specifying the object files as input to cl65?

Note that cl65 is intended to both compile & link. As you can see, I'm specifying the .asm source files in the cl65 source file list.
 

Schol-R-LEA

New Member
Sep 20, 2019
17
10
3
I just did my own little test of spliting your original example (to similarly seperate out the petscii print proc, into a seperate .include file), and I had no issues or errors. Compiled and ran perfectly. :)

This was using the following compile & link command (using your naming convention):
Code:
cl65 petscii-separate.asm petscii-print-separate.asm -t cx16 -C cx16-asm.cfg -o petscii-seperate.prg
I'm not sure why you are using ca65 to first compile, then specifying the object files as input to cl65?

Note that cl65 is intended to both compile & link. As you can see, I'm specifying the .asm source files in the cl65 source file list.
OK, yes, that does work for me now, too. I had been trying to use ld65 initially, assembling the individual files first and then linking them, but I couldn't get the stand-alone linker to work in that manner at all. I guess I was stuck in the thought pattern of 'I know that cl65 is a driver for the whole package, but I'm really just using it for the linking, so I should still assemble the source files separately'. Just a failure to see the obvious, I suppose. I feel like a bit of an idiot for that now.
 

GregZone

Member
Sep 29, 2019
32
20
8
OK, yes, that does work for me now, too. I had been trying to use ld65 initially, assembling the individual files first and then linking them, but I couldn't get the stand-alone linker to work in that manner at all. I guess I was stuck in the thought pattern of 'I know that cl65 is a driver for the whole package, but I'm really just using it for the linking, so I should still assemble the source files separately'. Just a failure to see the obvious, I suppose. I feel like a bit of an idiot for that now.
Completely understandable. Don't feel bad, we're all here on the learning curve and figuring things out as we go.
Sometimes the benefit of forums is just being able to find like-minded people to bounce-off. There's many cases where the solution reveals itself just through the process of bouncing the issue off others, plus others get the chance to learn from it as well! :)
 
May 22, 2019
486
250
43
There's many cases where the solution reveals itself just through the process of bouncing the issue off others, plus others get the chance to learn from it as well!
Back in the 90s, I was having some problems with a text editor, and my girlrfriend (who knows nothing about coding) happened to walk in as I was trying to figure out the issue. As I started to explain the problem to her, the answer presented itself in my mind. I love it when that happens.
 
  • Like
Reactions: GregZone

nattil

New Member
Oct 14, 2019
11
1
3
Back in the 90s, I was having some problems with a text editor, and my girlrfriend (who knows nothing about coding) happened to walk in as I was trying to figure out the issue. As I started to explain the problem to her, the answer presented itself in my mind. I love it when that happens.
It's often called Rubber Duck protocol. You can hold up a Rubber Duck and explain the problem to him, and often the solution suddenly presents itself. Don't explain this analogy to your spouse, as they don't prefer being compared to rubber ducks for some reason.
 

paradoxnj

New Member
Oct 7, 2019
1
3
1
Hi everyone,

If anyone is interested, I wrote a "Hello World" using cc65 using the VERA screen RAM instead of the CHAROUT kernal routine. I used the cc65-sprite demo as a reference and used the VERA documentation for everything else. You can compile it with:

cl65.exe -O -o hello.prg -t cx16 hello.c
Code:
#include <stdint.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <cbm.h>
#include <cbm_screen_charmap.h>
#include <cx16.h>

static void vpoke(uint8_t bank, uint16_t address, uint8_t data) {
    VERA.control = 0;
    VERA.address_hi = bank;
    VERA.address = address;
    VERA.data0 = data;
}

static void vera_set_addr(uint8_t bank, uint16_t address) {
    VERA.address_hi = bank;
    VERA.address = address;
}

static void clear_screen(uint8_t color) {
    char space = 32;
    uint8_t x;
    uint8_t y;

    vera_set_addr(0x10, 0x0000);
    for (y = 0; y < 60; y++) {
        VERA.address = (uint16_t)((y << 8) & 0xFF00);
        for (x = 0; x < 80; x++) {
            VERA.data0 = space;
            VERA.data0 = color;
        }
    }
}

void main(void) {
    int i;
    const char *szHello = "hello world!!";

    cbm_k_bsout(CH_FONT_UPPER);

    clear_screen(1);

    vera_set_addr(0x20, 0x0000);
    for (i = 0; i < strlen(szHello); i++) {
        VERA.data0 = szHello[i];
    }

    while (1){}
}
The output should look like the attached screenshot.cx16-hello.JPG

I am working on rendering a 256 color bitmap using mode7 but am having a hell of a time finding a file format to use. I started with C headers, but that didn't work as the data is too large. I am trying PCX now. As soon as I figure it out, I will post it here.
 
Last edited: