KickC Optimizing C-Compiler now supports Commander X16

All aspects of programming on the Commander X16.
Jesper Gravgaard
Posts: 16
Joined: Mon Dec 14, 2020 9:18 pm

KickC Optimizing C-Compiler now supports Commander X16

Post by Jesper Gravgaard »


KickC is a C-compiler for 6502-based platforms creating optimized and readable assembler code. 

The newest version 0.8.5 adds support for developing for the Commander X16 platform.

The compiler includes header-files and linker-files for the chipset of Commander X16. Also included is veralib.h and a conio.h implementation contributed by @svenvandevelde.

It also includes some example-programs that work in the emulator (and hopefully on the real platform). Below you can see a bit of the included sprites.c example program.


You can get it here: https://gitlab.com/camelot/kickc/-/releases



PS. I am the author of KickC.

Screenshot 2021-01-16 at 00.56.52.png

Screenshot 2021-01-16 at 00.57.33.png

User avatar
svenvandevelde
Posts: 488
Joined: Wed Dec 23, 2020 6:30 am
Location: Belgium, Antwerpen

KickC Optimizing C-Compiler now supports Commander X16

Post by svenvandevelde »


@Jesper Gravgaard Hi Jesper,

Congratulations with your compiler. This is a truly amazing work. Really!

Your compiler does a trade-off between efficiency (and it does it very, very well), and functionality.

It is also very transparent, the assembly code generated is readable, which makes it very useful for debugging or learning.

Kudos!

Sven

KICKC home page by Jesper Gravgaard.
My KICKC alpha with Commander X16 extensions.
TomXP411
Posts: 1761
Joined: Tue May 19, 2020 8:49 pm

KickC Optimizing C-Compiler now supports Commander X16

Post by TomXP411 »


Hi, @Jesper Gravgaard

I'm trying out Kick C (I appreciate it doesn't require CygWin just to compile some c code), but I can't get the examples to compile for the Commander X16. 

I'm getting this:

image.thumb.png.b23cd4b62ff8bc75037fbeeea121de6f.png

 

I tried adding veralib.c to the command line, and I get Redefinition of variable: vera_layer_config

The error on the initial compile is telling me there's a library or object file missing, but I can't figure out how to add it on the command line. Do I need to compile something else first to create the Commander X16 library file? What am I missing?

(On another note: the program compiled and ran perfectly on VICE without any errors. Thanks!)

** edit: figured it out. I had to add

#include <cx16.h>

#include <veralib.h>

To the program. Once I did that, everything started up. Now I just have to remember my old school C and console commands. 

Thanks! This works great!

 

Jesper Gravgaard
Posts: 16
Joined: Mon Dec 14, 2020 9:18 pm

KickC Optimizing C-Compiler now supports Commander X16

Post by Jesper Gravgaard »


Hi @TomXP411

Thank you for trying out KickC. I hope you like it, and would appreciate any feedback from you to improve it!


8 minutes ago, TomXP411 said:




The error on the initial compile is telling me there's a library or object file missing, but I can't figure out how to add it on the command line. Do I need to compile something else first to create the Commander X16 library file? What am I missing?



I have found out why you are getting the "Called procedure not found" error. It is an embarrassing forgotten include. If you add the following line at the top of lib/cx16-conio.c. then helloworld.c will compile as it should

#include <veralib.h>

In the other included CX16 example programs veralib.h is included in the main C-file, so the compiler is happy. 

Let me know, if this works for you. I will of course include the fix in the next release.

TomXP411
Posts: 1761
Joined: Tue May 19, 2020 8:49 pm

KickC Optimizing C-Compiler now supports Commander X16

Post by TomXP411 »



51 minutes ago, Jesper Gravgaard said:




Hi @TomXP411



Thank you for trying out KickC. I hope you like it, and would appreciate any feedback from you to improve it!



I have found out why you are getting the "Called procedure not found" error. It is an embarrassing forgotten include. If you add the following line at the top of lib/cx16-conio.c. then helloworld.c will compile as it should



#include <veralib.h>



In the other included CX16 example programs veralib.h is included in the main C-file, so the compiler is happy. 



Let me know, if this works for you. I will of course include the fix in the next release.



Yep, that worked! 

There are a couple of other minor nags, but they are not deal breakers: 

I'd like to be able to include -scale 2 in the command line to start the emulator, but when I tried to add that to the platform files, the emulator just didn't start at all... 

 printf seems to use conio.h, which appears to talk directly to VERA. This works fine when you need performance, but it loses a lot of CHROUT's functinality. No console sequences (ie: cursor movement, etc) and text can't be redirected to an output channel for saving to disk, printing, or RS-232. 

It might be nice if printf() used CHROUT to write to the screen, and cprintf used memory I/O to talk to the screen. This would let printf work as expected with PETSCII console sequences, and it would keep the BASIC screen in sync with the text from a C program. This is also, more or less, the standard behavior on PC compilers, and would make the transition easier for people used to that method of doing things. 

So my thought was to change the existing printf() definitions, with the VERA functions, to "cprintf" and introduce a new version of the printf functions that uses CHROUT. While this is slower, it will allow printf to be re-directed to a printer, to RS-232, or to a file - all things you can't do with cprintf().  I'd be happy to do the work; I need to brush up on my C, anyway - it's been a while since I've done any real work in ANSI C.

Also... dumb question, but I can't find any file I/O commands. Am I missing something, or do I need to implement the basic file I/O functions?

 

 

Jesper Gravgaard
Posts: 16
Joined: Mon Dec 14, 2020 9:18 pm

KickC Optimizing C-Compiler now supports Commander X16

Post by Jesper Gravgaard »


@TomXP411 "-scale 2" works for me, when I add it to /target/cx16.tgt . Just make sure you do not add it at the end of the command string. This is because the "-prg" option at the end of the string expects the filename of the generated PRG-file to follow immediately after. 

This is my working emulator-setting  "emulator": "x16emu -debug -scale 2 -run -prg",



As for printf() you are completely right that it is implemented on top of conio.h. Printf itself calls only cputc and cputs.

If you would contribute a conio.h implementation written on top of CHROUT that would be awesome!



 I will gladly merge it into KickC's CX16 library.



I will have to read up a bit more on printf(), cprintf() and best practice on other platforms before deciding exactly how to do the merge. It might be the optimal solution to have some way of specifying which implementation to use. Maybe some #define or a #pragma.

 

 

Jesper Gravgaard
Posts: 16
Joined: Mon Dec 14, 2020 9:18 pm

KickC Optimizing C-Compiler now supports Commander X16

Post by Jesper Gravgaard »



38 minutes ago, TomXP411 said:




Also... dumb question, but I can't find any file I/O commands. Am I missing something, or do I need to implement the basic file I/O functions?



I am afraid there is no basic file I/O functions currently included the library. 

I do not know the CX16 well enough yet. What type of storage does it support and  how does it read/write files?



 

TomXP411
Posts: 1761
Joined: Tue May 19, 2020 8:49 pm

KickC Optimizing C-Compiler now supports Commander X16

Post by TomXP411 »



1 hour ago, Jesper Gravgaard said:




I am afraid there is no basic file I/O functions currently included the library. 



I do not know the CX16 well enough yet. What type of storage does it support and  how does it read/write files?



It uses the same APIs as the Commodore 64. My current assembly file read code looks like this:

    lda #filename_len-filename

    ldx #<filename

    ldy #>filename

    jsr SETNAM

    lda #FILE_CHANNEL

    ldx #DEVICE_NUMBER

    ldy #SECONDARY_ADDRSS_DIR

    jsr SETLFS

    jsr OPEN

 

To actually read from the file, you need to call CHKIN with the file channel in A:

    ldx #FILE_CHANNEL

    jsr CHKIN

And then you use GETIN to read a byte from the channel:

    jsr GETIN   ; reads a byte to A

To check for EOF:

    jsr READST or LDA $0286 

Reading from $286 is much faster, sine READST has some other overhead that's unnecessary for an EOF check. I plan to resolve that issue by actually reading into the READST routine and grabbing the operand of the LDA instruction.

 

Closing a channel is very simple:

    jsr CLRCHN

    lda #FILE_CHANNEL

    jsr CLOSE 

I'm looking at this right now, but I won't be able to spend too much more time on it today, I have to head out to work in about an hour. 

 

The problem I'm currently having is that this code is optimizing "ret" as a constant, and it's not allocating memory for the return variable:

char fgetc(byte channel)

{

    char ret=0;

    asm {

        ldx channel

        jsr CHKIN

        jsr GETIN

        sta ret

        jsr CLRCHN

    }

    return ret;

}

 

looks like this in the ASM file:

// fgetc(byte zp($13) channel)

fgetc: {

    .label ret = 0

    .label channel = $13

    ldx channel

    jsr CHKIN

    jsr GETIN

    sta ret

    jsr CLRCHN

    rts

}

 

I think the problem is that the optimizer isn't seeing RET being used anywhere, so it's optimizing out the storage for ret and treating it as a constant. If I do something like "ret=ret+1" above the asm block, then it gets storage... but there are other issues I'm still working out.

 

Jesper Gravgaard
Posts: 16
Joined: Mon Dec 14, 2020 9:18 pm

KickC Optimizing C-Compiler now supports Commander X16

Post by Jesper Gravgaard »



1 hour ago, TomXP411 said:




 



The problem I'm currently having is that this code is optimizing "ret" as a constant, and it's not allocating memory for the return variable:



I think the problem is that the optimizer isn't seeing RET being used anywhere, so it's optimizing out the storage for ret and treating it as a constant. If I do something like "ret=ret+1" above the asm block, then it gets storage... but there are other issues I'm still working out.



 



If you add a volatile to ret it will not optimize it away. The compiler is not clever enough to recognize that you are modifying it inside the ASM.



It might be possible to examine the ASM instructions being applied to variables used inside ASM to detect if they can modify the variable. I will add that as a TODO.

Jesper Gravgaard
Posts: 16
Joined: Mon Dec 14, 2020 9:18 pm

KickC Optimizing C-Compiler now supports Commander X16

Post by Jesper Gravgaard »



1 hour ago, TomXP411 said:




It uses the same APIs as the Commodore 64. 



You might want to have a look at the example program /examples/kernalload/kernalload.c 

It loads a file on the C64 using the C64 KERNAL. 

Post Reply