All CC65 lib functions are weak

Since we do not have native C compilers on the Oric, this forum will be mostly be used by people using CC65 or the OSDK. But any general C related post will be welcome !
jsk
Officer Cadet
Posts: 60
Joined: Mon Jun 29, 2020 10:11 pm

Re: All CC65 lib functions are weak

Post by jsk »

xahmol wrote: Thu Jan 16, 2025 7:12 pm I still really do not understand what is wrong with the CC65 lib functions. They are fine and work fine.

CC65 itself as compiler compiles rather big code, but that will also be the case with making own lib functions for CC65.
My target is a ROM replacement to be run under LOCI, for a new programming language. That cannot rely on BASIC.

The CC65 (and OSDK?) oric library are all calling into the BASIC ROM, so Ive just written C-only replacment of that, allowing for a simple PING implementation etc, as well as reading keyboard.

It's not many lines of code...

Now, when it comes to printf, In my estimate it almost seems as if sprintf/printf are duplicates and quite big (2-3KB as you noted in later messages).

printf for printing simple integer numbers are quote slow, for whatever reason, it's a general thing. So I have a putint(), similar to putchar(), puts() and all just uses my cputc() which exists in various variants; a simple "unix-style tty", or one with full-screen editing.

Maybe I'll try to write a sprintf-replacement one day, lol.
User avatar
xahmol
Squad Leader
Posts: 619
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: All CC65 lib functions are weak

Post by xahmol »

Your statement ‘for a ROM’ makes perfect sense. Then I fully agree.
But that is not saying the functions are weak, they are just not suitable for that purpose…..

Normally calling ROM functions really is the way to go to produce smaller and faster code.

Then again, for writing ROMs where every byte counts, writing in C in CC65 is maybe not the best way for another reason, namely the rather big and ineffcient code the compiler creates even on own functions if not pure assembly.
Maybe especially for ROMs it would be worthwhile to investigate alternatives, especially as lib support is not an issue if you are writing your own functions anyway.
vbc
Officer Cadet
Posts: 34
Joined: Mon Feb 06, 2023 11:13 pm

Re: All CC65 lib functions are weak

Post by vbc »

xahmol wrote: Mon Jan 27, 2025 9:52 pm But that is not saying the functions are weak, they are just not suitable for that purpose…..
I think when the original poster called CC65 library functions weak, he pointed out that they work like weak symbols, i.e. they can be overridden with application specific functions (see e.g. https://en.wikipedia.org/wiki/Weak_symbol). It did not mean that the functions were bad.

Oh, and regarding the original question: Yes, this is common behaviour amongst C compilers and vbcc behaves the same. Not that I think this is very helpful two years after the original question. :)
User avatar
xahmol
Squad Leader
Posts: 619
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: All CC65 lib functions are weak

Post by xahmol »

Ah, thanks. Than I misunderstood. Learned something again.
jsk
Officer Cadet
Posts: 60
Joined: Mon Jun 29, 2020 10:11 pm

Re: All CC65 lib functions are weak

Post by jsk »

xahmol wrote: Mon Jan 27, 2025 9:52 pm Your statement ‘for a ROM’ makes perfect sense. Then I fully agree.
But that is not saying the functions are weak, they are just not suitable for that purpose…..

Normally calling ROM functions really is the way to go to produce smaller and faster code.

Then again, for writing ROMs where every byte counts, writing in C in CC65 is maybe not the best way for another reason, namely the rather big and ineffcient code the compiler creates even on own functions if not pure assembly.
Maybe especially for ROMs it would be worthwhile to investigate alternatives, especially as lib support is not an issue if you are writing your own functions anyway.
I have to disagree with that ROM-routines would be faster. I've written my own circle/line implementations in pure-C and they seem to be consistently around 30-50% faster. But sure, saves precious RAM to use the ROM.

I think with LOCI we will see many more programs compiled both as tap-files for BASIC ROM and as pure standalone ROM-code. Not sure if one can make a single universal binary with an "intermediary dispatch functionality". But it would require the binary to have to be relocatable., I think.

In my experience the minimal replacement for the ROM-routines aren't that big. I don't have an estimate of how big the Basics interpreter by itself is, but an guestimate would be 16-1k (charset)-2K (graphics/sound)-2K (float math)-1K (printing/screen)==> 11KB. Parsing all tha syntax may be costly. Maybe somebody has looked into the size of the various?

Yes, the codegen of CC65 is quote big, but from my little experience of other 6502 compilers it often generates more compact code (per routine), whereas other compilers seem to generate *super*optimized code but at 50-100% more byte-count!

One way to see the CC65 code is that it's like a byte-code machine where all the interpreter dispatch is replaced by generated JSR, JSR to a "small" kernerl-library of primitives.

I've looked at the design of the OSCAR compiler and it seems to be he right fit, especially if you can control the codegen to generate smaller code for code not run very often, or once.'

As for super optimized handwritten assembly - sure go ahead. I don't do it at first. First I try to figure out functionally, so I think it's fine for initial version to be C of conio etc, and be portable. Compilation can have flag to choose to use BASIC ROM or replace the functionally as appropriate. Eventually, bits and pieces can be replaced by ASM. But it is not my immediate goal. But squeezing everything into 16KB is the main goal.
User avatar
xahmol
Squad Leader
Posts: 619
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: All CC65 lib functions are weak

Post by xahmol »

jsk wrote: Tue Jan 28, 2025 12:04 pm I think with LOCI we will see many more programs compiled both as tap-files for BASIC ROM and as pure standalone ROM-code. Not sure if one can make a single universal binary with an "intermediary dispatch functionality". But it would require the binary to have to be relocatable., I think.
Do not know if I get what you mean here.
My LOCI File Manager is not a standalone ROM, but does not use a basic header either.
It makes use of the Loci functionality to auto load a tape, combined with the .TAP format option to auto execute machine code from the starting address, in my case $400.
But I do use the CC65 lib functions that do use ROM calls.
So not sure what this would make my program in what you mean here, nor what you mean with universal binary with ‘intermediate dispatch functionality’.
jsk
Officer Cadet
Posts: 60
Joined: Mon Jun 29, 2020 10:11 pm

Re: All CC65 lib functions are weak

Post by jsk »

Well, here is the thing, we don't have a "bios", with like interrupt facility to call system routines.

VIC64 had the KERNAL ( https://en.m.wikipedia.org/wiki/KERNAL ) that has guaranteed entry-pointer for various routines, like printing/reading files, a some other things.

Iff, for example the ORIC BASIC-ROM started/or ended with a jump table, or at least an entry-point that always stayed the same, any ROM could implement the same single entry/point, which basically is a calling indirection.

Now, instead C-code tap-files are jumping into various "random" BASIC-ROM addresses, and these are not the same for ORIC-1 and ORIC ATMOS, (Or telestrat for that matter?) and neither is it under the D-FLAT langauge ROM.

In any case, the question is currently moot, as we're still in early stages of the LOCI-revolution!

The most simple for me is just to use my own routines, independently of if there is a BASIC-ROM or not.
User avatar
xahmol
Squad Leader
Posts: 619
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: All CC65 lib functions are weak

Post by xahmol »

Check. Now I understand.
And yes, the CC65 lib so far is Atmos only. Or Telestrat only. Which I never considered to be an issue as the user base with a 1 and certainly a Telestrat is small.

Besides, I was developing for SEDORIC floppies and the floppy drive controller of floppy drives basically replaces the Oric 1 ROM with an Atmos one.
And now on Loci, it is also very easy to change the Oric 1 ROM for the Atmos one.

So even users with an Oric 1 can use my software, as my software is not usable without floppy drive or Loci.
So for me not supporting the Oric 1 ROM was never an issue.
User avatar
Dbug
Site Admin
Posts: 4989
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: All CC65 lib functions are weak

Post by Dbug »

That was one of the main drivers behind using floppy builder instead of Sedoric: The fact that it made it easy to have a game run on all machines independently of their ROM version.

Obviously that's not optimal for tools that need to manipulate and swap files, but I guess that's where the LOCI file system comes to the rescue :)
User avatar
Dbug
Site Admin
Posts: 4989
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: All CC65 lib functions are weak

Post by Dbug »

jsk wrote: Tue Jan 28, 2025 1:25 pm VIC64 had the KERNAL ( https://en.m.wikipedia.org/wiki/KERNAL ) that has guaranteed entry-pointer for various routines, like printing/reading files, a some other things.
In the case of the Oric it's even worse: Not even all zero page or page 2 addresses are the same on ROM 1.0 and 1.1, it's not just the lack of a jump table.
User avatar
xahmol
Squad Leader
Posts: 619
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: All CC65 lib functions are weak

Post by xahmol »

Commodore indeed did a very convenient job in making the jump table entriy points and system addresses in first two pages exactly the same (at least for the functions that all the systems had, obviously Plus/4 and C128 had additional entries for machine specific additions) over all Commodore machines, PET, VIC20, C64, C16/Plus/4 and C128.
This is indeed quite helpful as a large part of the CC65 lib functions that use kernal calls therefore can be CBM generic instead of targets for each machine separately.

But still also wondering how big the issue is, basically, how many people use an Oric 1 with the Oric 1 ROM? As both Erebus every floppy solution replace the ROM with an Atmos one.
So basically the only way without using a Maxduino tape loading emulation to get newly developed stuff with cross compilers to the Oric 1 is using a device that replaces the Oric 1 ROM. That is, before the LOCI came that now gives the option which ROM to use. But also that option gives also the option to use Atmos ROM.

Telestrat of course is a different discussion. But that also is obviously even way more niche in user base.

Obviously compiling from the same source to more than one compiler targets is rather trivial, but CC65 does not have an Oric 1 target. It does have a Telestrat target, so just making a make file that compiles for both Atmos and Telestrat targets is rather trivial apart from the fact that I can not test for Telestrat as I do not have one (and given its prices very likely never will have one).
The only time I was using the Telestrat target is when I tried to program for the Twilighte Board / ORIX platform which also uses the Telestrat target, but at that time the Telestrat libs were that immature that I gave up. Really basic things like cgetc(); we’re not properly working back then if I remember. And also the Twilighte Board itself was instable for me at best. That was I think three years ago though, so no clue what the maturity is now.
jsk
Officer Cadet
Posts: 60
Joined: Mon Jun 29, 2020 10:11 pm

Re: All CC65 lib functions are weak

Post by jsk »

Dbug wrote: Wed Jan 29, 2025 8:58 am That was one of the main drivers behind using floppy builder instead of Sedoric: The fact that it made it easy to have a game run on all machines independently of their ROM version.

Obviously that's not optimal for tools that need to manipulate and swap files, but I guess that's where the LOCI file system comes to the rescue :)
Ok, I see. I now only use CC65, not sure if floppy builder works, on it.

I'm assuming the DSK files generated works under LOCI, for running the "main" program?

Now, as it doesn't do updates, how different is it from a .tap-file with several "parts" files?

I've understood that (most) emulators support this and may even provide random access if loading by name (which of them does?), as it's basically an "oric-tar"-file, LOL. And if I understand it correctly these multi-parts would work on actual oric tape drives, at least if files are accessed in order.

It is promising that D-FLAT's loci implementation is quote small (?) and possibly provides a more generic interface, not sure how portable to DSK and other oric disk systems it is.

BTW: git clone gives funny errors (rpc) on downloading osdk, I'm in Thailand so maybe need to change chunk sizes....
User avatar
xahmol
Squad Leader
Posts: 619
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: All CC65 lib functions are weak

Post by xahmol »

jsk wrote: Wed Jan 29, 2025 1:59 pm Ok, I see. I now only use CC65, not sure if floppy builder works, on it.
Never tried it, but see no reason why CC65 would not work with Floppybuilder apart from the fact that you obviously need non-CC65 tooling (from OSDK) to build a DSK with floppy builder from CC65 created binaries,
Was actually my first plan for doing a Loci version of Oric Screen Editor before realising I do not need Floppybuilder for that on the Loci as you can just use the directory on the USB or internal storage instead of a DSK container. Much easier and works great in my Work in Progress built. See https://forum.defence-force.org/viewtop ... 157#p32157
Installation is as easy as unzip a ZIP with all required binaries plus one .TAP file to a dir on the USB stick and run the main .tap from the Loci interface.

But of course that only works with a Loci, so is not an option for those things that also want to support users without Loci.
User avatar
Dbug
Site Admin
Posts: 4989
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: All CC65 lib functions are weak

Post by Dbug »

jsk wrote: Wed Jan 29, 2025 1:59 pm
Dbug wrote: Wed Jan 29, 2025 8:58 am That was one of the main drivers behind using floppy builder instead of Sedoric: The fact that it made it easy to have a game run on all machines independently of their ROM version.

Obviously that's not optimal for tools that need to manipulate and swap files, but I guess that's where the LOCI file system comes to the rescue :)
Ok, I see. I now only use CC65, not sure if floppy builder works, on it.
No reason it would not work, the main thing would be that the loader code would have to be ported to run with CA65 with proper exports for the API.

jsk wrote: Wed Jan 29, 2025 1:59 pm Now, as it doesn't do updates, how different is it from a .tap-file with several "parts" files?
(...)
I've understood that (most) emulators support this and may even provide random access if loading by name (which of them does?), as it's basically an "oric-tar"-file, LOL. And if I understand it correctly these multi-parts would work on actual oric tape drives, at least if files are accessed in order.
As you said, the data can only be loaded in order with a tape, there's no automatic rewind to go to a part earlier on the tape.
An additional thing you get with the floppy builder system is the possibility to store data compressed on disk and it gets decompressed on the fly by the loading code without the need to an extra buffer.
jsk
Officer Cadet
Posts: 60
Joined: Mon Jun 29, 2020 10:11 pm

Re: All CC65 lib functions are weak

Post by jsk »

So, I was curious and wrote a simple printf-replacement in pure C.

It's little more limited. Only %scxdob with %03d but no %.5s function (actually limits output to 5chars), and no long support. Didn't even add the sign-position yet.

About 80 lines of compact C, and it comes out to 1701 bytes. You'll notice the cost of CC65 i 1870 bytes...

I did put something in register and already saved 100 bytes. But it's clear that the code-gen generates bloated, but more correct code than many other compilers. LOL. So the CC65-printf library isn't bad, as it packs functionality.

I'm guessing use of isdigit, strlen, and few other library routines may be one reason for the size.

// original: 2478 Bytes (+ 1870) // so +160 gives you better one?
// simple: 1962 Bytes (+ 1701)
// without: 611 Bytes (using puts)

In my estimate, basically you can write 3000 lines of C and then you've filled 37KB... No ram left. But writing assembly is soo much slower...

I'm interested in the Oscar hybrid variant of compliation. Also, I'd prefer compilers that concentrated on generating smaller code. For super-optimization, yeah, you usually have to go to assembly anyway.
iss wrote: Thu Jan 16, 2025 8:22 pm In regard of lib functions:
Attached are 2 TAPs compiled with CC65 and LLVM-MOS.
C source is the same - just printf("Hello world!");
Here the result size comes entirely from printf implementation in toolchain's standard library:

Code: Select all

printf-cc65.tap - 2770 bytes
printf-llvm.tap - 8258 bytes
Interesting numbers, right? :) No typo here llvm-mos printf is huge.

In common if your program fits in memory and works acceptable fast with the supplied libraries then no problem all happy, but if not - you know ... use assembler, Luke! :lol:
Post Reply