Calypsi C compiler toolchain for 6502 and 65816
Re: Calypsi C compiler toolchain for 6502 and 65816
This is great! I have a SuperCPU 128 for the Commodore 128. Will be looking into this with great interest.
Re: Calypsi C compiler toolchain for 6502 and 65816
Please consider at least running a github if only for your example code and updated binaries so that we can post issues. Since this appears to be the only place to talk with you and provide feedback, I have no choice but to post a long message.
Im creating a c64 target (for the supercpu), but calls to main() are always a byte or two off.
Heres the build commands:
Here is my cstartup.s (with my modifications):
https://imgur.com/a/9lfFU4o
Im creating a c64 target (for the supercpu), but calls to main() are always a byte or two off.
Heres the build commands:
Code: Select all
as65816 c64startup.asm -o c64startup.o -l --code-model small --data-model large
as65816 c64.asm -o c64.o -l --code-model small --data-model large
cc65816 test.c -o test.o -l --code-model small --data-model large
ln65816 test.o c64.o c64startup.o rules.scm clib-sc-ld.a --rtattr cstartup=c64startup --output-format raw -l --cross-reference
Code: Select all
.rtmodel cstartup,"c64startup"
.rtmodel version, "1"
.rtmodel cpu, "*"
.section stack
.section cstack
.section heap
.section data_init_table
.extern main, exit
.extern _Dp, _Vfp
.extern _DirectPageStart
#ifndef __CALYPSI_DATA_MODEL_SMALL__
.extern _NearBaseAddress
#endif
#include "macros.h"
;;; ***************************************************************************
;;;
;;; The reset vector. This uses the entry point label __program_root_section
;;; which by default is what the linker will pull in first.
;;;
;;; ***************************************************************************
.section reset
.pubweak __program_root_section
__program_root_section:
.word __program_start
;;; ***************************************************************************
;;;
;;; __program_start - actual start point of the program
;;;
;;; Set up CPU stack, initialize sections and call main().
;;; You can override this with your own routine, or tailor it as needed.
;;; The easiest way to make custom initialization is to provide your own
;;; __low_level_init which gets called after stacks have been initialized.
;;;
;;; ***************************************************************************
.section code,noreorder
.pubweak __program_start
__program_start:
; provides BASIC startup: "10 SYS 2062"
.byte 0x01, 0x08 ; always zero, load address
.byte 0x07, 0x08 ; pointer to next line
.byte 0x0A, 0x00 ; line number (10)
.byte 0x9e ; SYS token
.ascii " 2062" ; SYS address in ASCII
.byte 0, 0, 0 ; end-of-program
clc
xce ; native 16-bit mode
rep #0x38 ; 16-bit registers, no decimal mode
ldx ##.sectionEnd stack
txs ; set stack
lda ##_DirectPageStart
tcd ; set direct page
#ifdef __CALYPSI_DATA_MODEL_SMALL__
lda ##0
#else
lda ##.word2 _NearBaseAddress
#endif
stz dp:.tiny(_Vfp+2)
xba ; A upper half = data bank
pha
plb ; pop 8 dummy
plb ; set data bank
;;; **** Initialize data sections if needed.
; .section code, noroot, noreorder
; .pubweak __data_initialization_needed
; .extern __initialize_sections
;__data_initialization_needed:
; lda ##.word2 (.sectionEnd data_init_table)
; sta dp:.tiny(_Dp+6)
; lda ##.word0 (.sectionEnd data_init_table)
; sta dp:.tiny(_Dp+4)
; lda ##.word2 (.sectionStart data_init_table)
; sta dp:.tiny(_Dp+2)
; lda ##.word0 (.sectionStart data_init_table)
; sta dp:.tiny(_Dp+0)
; call __initialize_sections
;;; **** Initialize streams if needed.
; .section code, noroot, noreorder
; .pubweak __call_initialize_global_streams
; .extern __initialize_global_streams
;__call_initialize_global_streams:
; call __initialize_global_streams
;;; **** Initialize heap if needed.
; .section code, noroot, noreorder
; .pubweak __call_heap_initialize
; .extern __heap_initialize, __default_heap
;__call_heap_initialize:
;#ifdef __CALYPSI_DATA_MODEL_SMALL__
; lda ##.sectionSize heap
; sta dp:.tiny(_Dp+2)
; lda ##.sectionStart heap
; sta dp:.tiny(_Dp+0)
; lda ##__default_heap
;#else
; lda ##.word2 (.sectionStart heap)
; sta dp:.tiny(_Dp+6)
; lda ##.word0 (.sectionStart heap)
; sta dp:.tiny(_Dp+4)
; lda ##.word2 __default_heap
; sta dp:.tiny(_Dp+2)
; lda ##.word0 __default_heap
; sta dp:.tiny(_Dp+0)
; ldx ##.word2 (.sectionSize heap)
; lda ##.word0 (.sectionSize heap)
;#endif
; call __heap_initialize
.section code, root, noreorder
lda ##0 ; argc = 0
call main
rts
Re: Calypsi C compiler toolchain for 6502 and 65816
heres some more info:
whats happening here is that the JSR to call main (082a) is instead skipping two bytes and hitting the BRK. Looks like a problem in the linker perhaps.
Code: Select all
.C:0826 20 2C 08 JSR $082C
.C:0829 60 RTS
.C:082a A9 00 LDA #$00
.C:082c 00 BRK
.C:082d 6B RTL
Re: Calypsi C compiler toolchain for 6502 and 65816
How does __program_start get its value? C64 program files start with a two byte load address, which you are providing. But those bytes do not get loaded. If __program_start is $0801, the assembler will believe that everything is two bytes higher than it actually is.
If you can set it to $07ff, then the first bytes to be loaded (.byte 0x07, 0x08) will be at $0801, everything will be where it should be, and it should start working.
If you can set it to $07ff, then the first bytes to be loaded (.byte 0x07, 0x08) will be at $0801, everything will be where it should be, and it should start working.
Re: Calypsi C compiler toolchain for 6502 and 65816
It actually properly creates the BASIC portion as is.
Re: Calypsi C compiler toolchain for 6502 and 65816
John - your note gave me an idea.. the load address isnt really code, so I tried dropping it, doing the compile, and then adding it back using a hex editor after the prg file was created. Seems to work now. I guess a post build step would be needed afterward to add the load address. Thank you!
Re: Calypsi C compiler toolchain for 6502 and 65816
a question for OP. docs say:
What determines when parameters are passed on the stack vs registers?
Quote:
18.3 Calling convention
The calling convention is fairly complex in all its details, but for most common situations it is reasonable
simple.
If parameters are passed on the stack the caller is responsible for doing any cleanup. The called function can
use any register resource, but it must obey that certain registers are to be preserved. If using registers that
shall be preserved, the called function is responsible for saving the current value and then restore it before
giving control back.
Parameters are passed in the A accumulator, index register X and pseudo registers _Dp[0-7].
Registers A, X, Y and pseudo registers 07 are destroyed by a function call. Pseudo registers 815 must be
preserved.
The calling convention is fairly complex in all its details, but for most common situations it is reasonable
simple.
If parameters are passed on the stack the caller is responsible for doing any cleanup. The called function can
use any register resource, but it must obey that certain registers are to be preserved. If using registers that
shall be preserved, the called function is responsible for saving the current value and then restore it before
giving control back.
Parameters are passed in the A accumulator, index register X and pseudo registers _Dp[0-7].
Registers A, X, Y and pseudo registers 07 are destroyed by a function call. Pseudo registers 815 must be
preserved.
Re: Calypsi C compiler toolchain for 6502 and 65816
xlar54 wrote:
Please consider at least running a github if only for your example code and updated binaries so that we can post issues. Since this appears to be the only place to talk with you and provide feedback, I have no choice but to post a long message.
Im creating a c64 target (for the supercpu), but calls to main() are always a byte or two off.
Heres the build commands:
Im creating a c64 target (for the supercpu), but calls to main() are always a byte or two off.
Heres the build commands:
Code: Select all
as65816 c64startup.asm -o c64startup.o -l --code-model small --data-model large
as65816 c64.asm -o c64.o -l --code-model small --data-model large
cc65816 test.c -o test.o -l --code-model small --data-model large
ln65816 test.o c64.o c64startup.o rules.scm clib-sc-ld.a --rtattr cstartup=c64startup --output-format raw -l --cross-reference
For the Commodore 64 and similar projects, you could use the https://github.com/hth313/Calypsi-6502-Commodore project. That is intended for board support for C64 and related computers. I will consider a more generic Calypsi project on Github for issues that does not fit into particular board support.
Re: Calypsi C compiler toolchain for 6502 and 65816
xlar54 wrote:
a question for OP. docs say:
What determines when parameters are passed on the stack vs registers?
What determines when parameters are passed on the stack vs registers?
Re: Calypsi C compiler toolchain for 6502 and 65816
hth313 wrote:
xlar54 wrote:
Please consider at least running a github if only for your example code and updated binaries so that we can post issues. Since this appears to be the only place to talk with you and provide feedback, I have no choice but to post a long message.
Im creating a c64 target (for the supercpu), but calls to main() are always a byte or two off.
Heres the build commands:
Im creating a c64 target (for the supercpu), but calls to main() are always a byte or two off.
Heres the build commands:
Code: Select all
as65816 c64startup.asm -o c64startup.o -l --code-model small --data-model large
as65816 c64.asm -o c64.o -l --code-model small --data-model large
cc65816 test.c -o test.o -l --code-model small --data-model large
ln65816 test.o c64.o c64startup.o rules.scm clib-sc-ld.a --rtattr cstartup=c64startup --output-format raw -l --cross-reference
For the Commodore 64 and similar projects, you could use the https://github.com/hth313/Calypsi-6502-Commodore project. That is intended for board support for C64 and related computers. I will consider a more generic Calypsi project on Github for issues that does not fit into particular board support.
Code: Select all
F:\Software\Emulation\Commodore\Development\projects\8086tiny\64test>ln65816 test.o c64.o c64startup.o rules.scm clib-sc-ld.a --rtattr cstartup=c64startup --output-format prg -l --cross-reference
option --output-format: unexpected "pr" or 'p'
expecting "intel-hex", "pgz", "raw", or "s-record"
Last edited by xlar54 on Fri Feb 25, 2022 1:47 am, edited 1 time in total.
Re: Calypsi C compiler toolchain for 6502 and 65816
hth313 wrote:
xlar54 wrote:
a question for OP. docs say:
What determines when parameters are passed on the stack vs registers?
What determines when parameters are passed on the stack vs registers?
- Sheep64
- In Memoriam
- Posts: 311
- Joined: 11 Aug 2020
- Location: A magnetic field
Re: Calypsi C compiler toolchain for 6502 and 65816
Thank you for working on a C compiler. The 6502 Forum can be a tough crowd and I've had difficulty complimenting work on a C compiler. Although many people are dis-inclined to support C on 6502, that has been a futile objection since cc65 was released.
To obtain trustworthy execution of C on 6502, we require three or more compilers which are able to compile each other - or another technique yet to be discovered/published. In 1984, Ken Thompson's Reflections on Trusting Trust explained how to hide malware in a compiler. The malware, as implemented and distributed, was a quine which identified when the compiler was being compiled and added a branch to the parse tree. The purpose of the branch was to identify compilation of the Unix login program and also modify its parse tree. This allowed a specific username/password to obtain elevated privileges on any affected system. Compilation of the compiler or login program produced the same binary and none of the unwanted functionality appeared in the source code.
Eliminating such quines requires three or more independent compilers where there is no collusion. This specifically requires compilers which are maintained in separate repositories and are maintained by teams without overlap.
Thank you for being one of these critical teams.
Please do not host any operating system or language with a subsidiary of a direct competitor and convicted monopolist. The 6502 Forum already has difficulty with a Microsoft subsidiary regarding email. We don't need problems with another subsidiary. Actually, I believe that it is highly questionable to host the primary copy of EhBASIC on Github. That'll work until it doesn't.
Of particular note for a C compiler, Github restricts the names of insecure POSIX functions. There is no such restriction for insecure Microsoft functions.
To obtain trustworthy execution of C on 6502, we require three or more compilers which are able to compile each other - or another technique yet to be discovered/published. In 1984, Ken Thompson's Reflections on Trusting Trust explained how to hide malware in a compiler. The malware, as implemented and distributed, was a quine which identified when the compiler was being compiled and added a branch to the parse tree. The purpose of the branch was to identify compilation of the Unix login program and also modify its parse tree. This allowed a specific username/password to obtain elevated privileges on any affected system. Compilation of the compiler or login program produced the same binary and none of the unwanted functionality appeared in the source code.
Eliminating such quines requires three or more independent compilers where there is no collusion. This specifically requires compilers which are maintained in separate repositories and are maintained by teams without overlap.
Thank you for being one of these critical teams.
xlar54 on Wed 23 Feb 2022 wrote:
Please consider at least running a github if only for your example code and updated binaries so that we can post issues.
Of particular note for a C compiler, Github restricts the names of insecure POSIX functions. There is no such restriction for insecure Microsoft functions.
Re: Calypsi C compiler toolchain for 6502 and 65816
Please, don't bother with the "convicted monopoly" stuff - it's not the case that "the forum has trouble with" any supplier or company - it's only true, and can only be true, that specific people hold particular opinions.
It never moves a conversation forward in a good way to make these kinds of value-laden comments, or to repeat them. It's just tribal signalling. We do very much better here, in a technical hobby, to put all those things aside, and stick to the technical topics.
It never moves a conversation forward in a good way to make these kinds of value-laden comments, or to repeat them. It's just tribal signalling. We do very much better here, in a technical hobby, to put all those things aside, and stick to the technical topics.
Re: Calypsi C compiler toolchain for 6502 and 65816
Just to let you know that my C compiler tools are now available from https://www.calypsi.cc/
I released 3.6.2 yesterday, but I do not plan to post here every time I make a release in the future, just check the page out from time to time if you are interested.
I released 3.6.2 yesterday, but I do not plan to post here every time I make a release in the future, just check the page out from time to time if you are interested.
Re: Calypsi C compiler toolchain for 6502 and 65816
xlar54 wrote:
Ok, and then anything it cant place in a register, it puts on the stack?
Sorry for the late answer.