Calypsi C compiler toolchain for 6502 and 65816
Re: Calypsi C compiler toolchain for 6502 and 65816
Is it too early in this diversion to suggest we get back to the topic of the thread, and if we want to argue (again) about assembler syntax, we can make another thread for it?
Re: Calypsi C compiler toolchain for 6502 and 65816
BillG wrote:
I never liked the split format. In those days of slow and small storage devices, that added space was wasteful.
Quote:
It is insightful that the split format was deprecated in documentation for the 6809 and more notably, the 6801/6803 which sported some extensions of the original instruction set but was otherwise source and binary compatible.
If this all seems rather silly to you, well, yes, it does to me, too, which is why I don't go around yelling at people who don't use whatever I feel should be "standard" mnemonics while making statements that are either ignorant or deliberately misleading. (BDD has never addressed the fact that the initial manuals used only three-character mnemonics, and clearly did not consider the "A," or "B," in the operand field to be part of the mnemonic.)
Curt J. Sampson - github.com/0cjs
Re: Calypsi C compiler toolchain for 6502 and 65816
BigDumbDinosaur wrote:
Speaking of the user guide, I did see some information that was presented about the 65C816's memory model that I'd like to discuss in the interest of clarity. Also, I have some curiosity about how the compiler resolves some things that are more-or-less 65C816-specific. Please note that the following is not criticism, just an attempt to reconcile what the guide says with what I know about the 816's behavior.
[...]
In 6502-family architecture, a "page" is defined as 256 contiguous bytes, not 64KB. In 65C816 architecture, a "bank" is defined as 256 contiguous pages, with any given bank starting at $xx0000, where $xx is the bank number, $00-$FF.¹
[...]
In 6502-family architecture, a "page" is defined as 256 contiguous bytes, not 64KB. In 65C816 architecture, a "bank" is defined as 256 contiguous pages, with any given bank starting at $xx0000, where $xx is the bank number, $00-$FF.¹
I agree about the 'page' being incorrect. However, while bank is probably according to the 65816, I think it can be misleading too, as I often regard bank to be something that is switched in and out in some address range.
I will give it some further thought (sleep on it), but I think segment may be a better universal term as you suggest in the footnote. Not everyone that uses the compiler can be expected to be familiar with the target and one reason for using a C compiler is to avoid having to learn and write in the native assembly language.
Quote:
As for the statement about efficiency, I question that. The 65C816 assembly language makes it possible to treat the full address space as linear space for data purposes, using succinct code. This possibility is fully exploited if "long" pointers are handled as 32-bit entities instead of 24-bit so frequent use of REP and SEP in pointer arithmetic sequences can be avoided.²
Accessing as memory location using either a Far or Huge pointer will most likely result in the same code. There are two cases where they differ. The most important one is in pointer arithmetic, which can be adding a value to the pointer (stepping it). In some cases this does not matter as an addressing mode can be used, but in other cases it needs to actually perform pointer arithmetic and with a Far pointer this is done on the low 16 bits, while a Huge pointer needs 32 bits arithmetic. It also matters for size_t, which depending on how the compiler is configured can be 16 bits when Far is used, but if Huge is enabled size_t is 32 bits. The size_t type is used in some C library functions.
As an example, consider adding one to a pointer and passing it on. In this case the pointer needs to be updated, there is no addressing mode to help as it is going to pass an update pointer value. With a Far pointer this can typically be done using a single INC instruction. With a Huge pointer it would need an INC-BNE-INC sequence.
So I think that there is a performance difference between them, but I suppose it depends on what operations you actually do.
Quote:
Is the "stack" being referred to in the above the MPU's hardware stack or a LIFO in bank $00 being treated as a stack, e.g., like the data stack commonly used in Forth? If the latter, perhaps that should be clarified for the benefit of the reader.
If the former, I'm a little confused by the As we may want to point to object in the stack, they must be in the same page. statement. Wouldn't such an object be accessible with <offset>,S (stack-relative) addressing, which implicitly refers to bank $00 and does not involve DB in any way?
The Small data model assumes a 16 bits default data pointer. Yes, you can access an object on the stack using an addressing mode even the bank register points elsewhere. This is utilized in all data models.
You an also place a static or global object in a bank that is not 0 and address it using the absolute addressing mode.
Now consider that you want the address of either of these objects, a stack object or a data object in some other bank pointed to by the bank register. It may be a buffer that to pass to sprintf(). If you make the pointer 16 bits, which bank should sprintf() access? There is no way for it to know and both can be used by normal C code.
To make it work, both are forced to be in bank 0 in the Small data model. This allows for 16 bits default (untyped) pointers that can point to any data object.
If you want to use separate banks, then you need a 32 bits pointer and this is what the Medium data model is all about.
Quote:
malloc() and free() calls (which is really a separate issue, I think), what other (possibly bad) things could happen in a memory-constrained environment? Also, how and when is the size of the heap determined? Is the heap limited to a single bank or can it be defined to span multiple banks to accommodate malloc() calls that request more than 64KB?
The bad thing that can happen in a memory constrained system apart from heap fragmentation (as you mention) is that you try to fit too much program into the available memory and run out of memory space. If you write a program for you Linux desktop, I doubt you worry that will happen.
The heap is set up in the linker memory rules file (.scm extension). You can set the heap size and stack size there.
At the moment there is only one heap and it is not possible (in its prebuilt form) to make it span multiple banks. The library C code itself can actually handle it, but it needs to be properly configured and rebuilt for it. I need to fix the library build tool so end user can do it. This is one thing that is not done yet and it is mentioned in the release notes. If you actually use the compiler and run into issues with this limitation, I will put higher priority on fixing it, otherwise it will come at some point.
Quote:
If you write 'register int x=0' inside a function it will either be located in a register or on the hardware stack.
Quote:
$01FFFF? Also, does the compiler have a way to handle memory "holes" caused by idiosyncratic address decoding?
The Foenix C256 comes with 6Mb and the coming GenX model will fill the entire 16Mb address space and then add some banked (!) memory on top of that (it has some 64MB in total), but I do not plan to support that anytime soon. I am happy to limit it to 16MB and I doubt I will write any program I want to run on my 65816 system that uses all that memory.
Quote:
I am aware of the there are standards or ways that people expect assemblers to behave. However, this is a C compiler and the most important products in the package are the compiler and the debugger as I see it. The assembler is mainly there to support the compiler. I did not write this to be a 6502/65816 compiler tool chain, that sort of happened by accident. The code base will be used to make additional targets, this work is in progress. I decided not to care too much about assembler expressions and specific vendor features. I do try to follow defined mnemonics and addressing mode syntax. In the end I provide what is needed for myself and the compiler in a way that makes it efficient for me to work with it.
I have little hope for that my assemblers will make anyone switch from their favourite tools they been using for a decade or two. My take is that people who use a C compiler tool chain do it because they want to write as little assembly language as possible.
Quote:
switch() statement, as read-only data, as in:
Code: Select all
switch (i) {
case 1: printf("i = 1.\n");
break;
case 2: printf("i = 2.\n");
break;
...etc...
default: printf("i is not 1 or 2.\n");
}Re: Calypsi C compiler toolchain for 6502 and 65816
BigDumbDinosaur wrote:
BigDumbDinosaur wrote:
hth313 wrote:
- The huge address space covers the entire 16MB address range. The maximum size of an object is 16MB (minus one byte).
In the UNIX/Linux environment, sbrk() would be called by malloc() when the heap was (nearly) exhausted and more memory was needed to satisfy future requests (I'm cheerfully assuming that no free() calls are made in the running program, which means it will likely increase its memory consumption the longer it runs). sbrk(), in turn, would try to "find" memory, either physical or virtual, with the latter possible in a machine whose MPU supports the concept of virtual memory.¹
Given that, the Calypsi compiler's rendition of malloc() would have to have some way to know how to enlarge the heap when nearly exhausted. Doing so would either require the malloc() code have knowledge of the machine's physical memory map, or malloc() would have to know how to request more memory from the operating environment on which the executable is running.
Please clarify.
——————————
¹It is theoretically possible to build a virtual-memory system using the 65C816. The ABORTB interrupt input provides the basic means by which program execution may be temporarily stopped to allow the kernel to deal with a page fault. ABORTB' behavior is sub-optimal, but that is not an insurmountable obstacle in a system that uses a CPLD or FPGA to implement glue logic.
As this mainly is for bare metal programs, the heap for malloc() is statically allocated at link time in a fixed address range at the moment. There are no means for growing it beyond what you have defined it at the time of linking the program.
If you want to run on some theoretical operating system that can invent memory, you would need to replace some C library routines. As I mentioned in my previous answer, it will be possible to rebuild the library at some point. In theory, that would allow anyone to make their own C library flavour. This is however beyond what I plan to do with the tool chain.
-
mysterymath
- Posts: 79
- Joined: 10 Jan 2021
Re: Calypsi C compiler toolchain for 6502 and 65816
hth313 wrote:
I did not write this to be a 6502/65816 compiler tool chain, that sort of happened by accident.
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Calypsi C compiler toolchain for 6502 and 65816
mysterymath wrote:
hth313 wrote:
I did not write this to be a 6502/65816 compiler tool chain, that sort of happened by accident.
It appears this compiler is specific to the 65C816, which is a much better target for a C compiler than the 65(c)02. The user guide goes into some detail in that regard.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: Calypsi C compiler toolchain for 6502 and 65816
mysterymath wrote:
hth313 wrote:
I did not write this to be a 6502/65816 compiler tool chain, that sort of happened by accident.
Around the time when I released the 6502 product I ran into the C256 Foenix people. This caused me to take an additional look at the 65816 and I decided to make a product for it too, as it looked like an interesting challenge. So it happened due to this.
Otherwise there are other targets I am working on to be released in the future. This includes a variety of 8, 16 and 32 bit targets.
Making it work on several targets early on and more or less at the same time helps to avoid the trap of making a product suitable for one or few styles of targets. Yet, I need to make it possible to utilize the various idiosyncrasies of the targets, so it is a balance.
Re: Calypsi C compiler toolchain for 6502 and 65816
New release, version 3.4.1 of my C compiler for 6502 and 65816.
The user guides now contain a tutorial showing how to build a simple Hello World for running either on the included debugger (using its simulator) or on target hardware/emulator using VICE for Commodore 64 (6502) and the C256 Foenix emulator (65816).
Short overview of what is new (there are more details in the release notes in the installation):
Installers are available here:
6502
User guide (pdf) https://tinyurl.com/38m6u67r
Arch https://tinyurl.com/5wtzdb74
Debian https://tinyurl.com/26xbeebm
macOS https://tinyurl.com/yz6pefn6
65816
User guide (pdf) https://tinyurl.com/4yy9u3jb
Arch https://tinyurl.com/2dm3vh7k
Debian https://tinyurl.com/be74jffd
macOS https://tinyurl.com/5cj283b7
The user guides now contain a tutorial showing how to build a simple Hello World for running either on the included debugger (using its simulator) or on target hardware/emulator using VICE for Commodore 64 (6502) and the C256 Foenix emulator (65816).
Short overview of what is new (there are more details in the release notes in the installation):
- The optimizer can now perform inlining
- Custom section names can be used for code and data objects
- Alignment can be specified on C objects
- Better support for replacing the C startup module
Installers are available here:
6502
User guide (pdf) https://tinyurl.com/38m6u67r
Arch https://tinyurl.com/5wtzdb74
Debian https://tinyurl.com/26xbeebm
macOS https://tinyurl.com/yz6pefn6
65816
User guide (pdf) https://tinyurl.com/4yy9u3jb
Arch https://tinyurl.com/2dm3vh7k
Debian https://tinyurl.com/be74jffd
macOS https://tinyurl.com/5cj283b7
Re: Calypsi C compiler toolchain for 6502 and 65816
New version 3.4.3 available. This is a maintenance release with bug fixes.
65816 6502
65816 6502
Re: Calypsi C compiler toolchain for 6502 and 65816
Great to see it, thanks Håkan!
Re: Calypsi C compiler toolchain for 6502 and 65816
wouldn't it make more sense to make a github repo for this? so you wouldn't need to post new links for every update, and you wouldn't need version numbers when installing as it would just grab whatever is the newest.
i tried installing the 65816 version via the commandline (Ubuntu, WSL2) and running "sudo gdebi calypsi-nut-3.4.3.deb" just gives me a "file not found" error.
the user guide says 3.4.1 but i assume you're supposed to replace that with whatever version is the current one. even changing it to 3.4.1 still gives me the same error.
i'm sorry but i don't know how you're supposed to install this.
i tried installing the 65816 version via the commandline (Ubuntu, WSL2) and running "sudo gdebi calypsi-nut-3.4.3.deb" just gives me a "file not found" error.
the user guide says 3.4.1 but i assume you're supposed to replace that with whatever version is the current one. even changing it to 3.4.1 still gives me the same error.
i'm sorry but i don't know how you're supposed to install this.
Re: Calypsi C compiler toolchain for 6502 and 65816
Proxy wrote:
wouldn't it make more sense to make a github repo for this? so you wouldn't need to post new links for every update, and you wouldn't need version numbers when installing as it would just grab whatever is the newest.
i tried installing the 65816 version via the commandline (Ubuntu, WSL2) and running "sudo gdebi calypsi-nut-3.4.3.deb" just gives me a "file not found" error.
the user guide says 3.4.1 but i assume you're supposed to replace that with whatever version is the current one. even changing it to 3.4.1 still gives me the same error.
i'm sorry but i don't know how you're supposed to install this.
i tried installing the 65816 version via the commandline (Ubuntu, WSL2) and running "sudo gdebi calypsi-nut-3.4.3.deb" just gives me a "file not found" error.
the user guide says 3.4.1 but i assume you're supposed to replace that with whatever version is the current one. even changing it to 3.4.1 still gives me the same error.
i'm sorry but i don't know how you're supposed to install this.
Do you have gdebi installed? The installer .deb file is just the file you downloaded. If it goes to a downloads directory and you are in another directory, you need to specify the path to it.
Re: Calypsi C compiler toolchain for 6502 and 65816
I have made a new release version 3.5.1.
This release adds support for 64 bit IEEE floating point and the debugger can be used for target debugging. At the moment I only have a debugger agent for the C256U here https://github.com/hth313/Calypsi-remote-debug.git
6502
68000
This release adds support for 64 bit IEEE floating point and the debugger can be used for target debugging. At the moment I only have a debugger agent for the C256U here https://github.com/hth313/Calypsi-remote-debug.git
6502
- Arch https://tinyurl.com/2xesvt5p
- Debian https://tinyurl.com/e2auuf8f
- macOS https://tinyurl.com/am72pz5j
- Windows https://tinyurl.com/jjt2ysjx
- doc https://tinyurl.com/28wpxn88
- Arch https://tinyurl.com/5n88wfn6
- Debian https://tinyurl.com/2p8av29n
- macOS https://tinyurl.com/mwt3dxzc
- Windows https://tinyurl.com/2p98hnum
- doc https://tinyurl.com/5n98f4r2
68000
Re: Calypsi C compiler toolchain for 6502 and 65816
Thanks for the updates! Having the sources to build things ourselves is a neat idea, though I do prefer the .deb files you've been offering.