6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 2:38 pm

All times are UTC




Post new topic Reply to topic  [ 82 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
Author Message
PostPosted: Mon Feb 07, 2022 3:27 am 
Offline

Joined: Wed Oct 18, 2017 1:26 am
Posts: 28
This is great! I have a SuperCPU 128 for the Commodore 128. Will be looking into this with great interest.


Top
 Profile  
Reply with quote  
PostPosted: Wed Feb 23, 2022 3:44 am 
Offline

Joined: Wed Oct 18, 2017 1:26 am
Posts: 28
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:
Code:
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

Here is my cstartup.s (with my modifications):
Code:
            .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


https://imgur.com/a/9lfFU4o


Top
 Profile  
Reply with quote  
PostPosted: Wed Feb 23, 2022 7:13 pm 
Offline

Joined: Wed Oct 18, 2017 1:26 am
Posts: 28
heres some more info:

Code:
.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


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.


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 24, 2022 12:15 am 
Offline

Joined: Tue Sep 03, 2002 12:58 pm
Posts: 336
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.


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 24, 2022 6:44 am 
Offline

Joined: Wed Oct 18, 2017 1:26 am
Posts: 28
It actually properly creates the BASIC portion as is.


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 24, 2022 6:53 am 
Offline

Joined: Wed Oct 18, 2017 1:26 am
Posts: 28
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!


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 24, 2022 4:01 pm 
Offline

Joined: Wed Oct 18, 2017 1:26 am
Posts: 28
a question for OP. docs say:

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.


What determines when parameters are passed on the stack vs registers?


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 24, 2022 6:13 pm 
Offline

Joined: Sun Oct 07, 2018 6:04 pm
Posts: 30
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:
Code:
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



You should use --output-format=prg for Commodore 64 rather than raw. It adds the start address before raw output, otherwise these format are the same.

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.


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 24, 2022 6:24 pm 
Offline

Joined: Sun Oct 07, 2018 6:04 pm
Posts: 30
xlar54 wrote:
a question for OP. docs say:

What determines when parameters are passed on the stack vs registers?


The safest is to look at the generated code. What it does is to scan the parameter list left to right and bind registers in a given order. First it uses the CPU register(s) for a single parameter, then it will take the DP pseudo registers. If a parameter cannot fit in register, it will look further down the parameter list for a possible candidate to put in register.


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 25, 2022 1:40 am 
Offline

Joined: Wed Oct 18, 2017 1:26 am
Posts: 28
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:
Code:
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



You should use --output-format=prg for Commodore 64 rather than raw. It adds the start address before raw output, otherwise these format are the same.

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.


I might have an older version of the compiler, as prg isnt an option. Mine is v3.5.1. (Also note that Im using the 65816 target as the supercpu has an 65816 in it)

Code:
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.

Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 25, 2022 1:43 am 
Offline

Joined: Wed Oct 18, 2017 1:26 am
Posts: 28
hth313 wrote:
xlar54 wrote:
a question for OP. docs say:

What determines when parameters are passed on the stack vs registers?


The safest is to look at the generated code. What it does is to scan the parameter list left to right and bind registers in a given order. First it uses the CPU register(s) for a single parameter, then it will take the DP pseudo registers. If a parameter cannot fit in register, it will look further down the parameter list for a possible candidate to put in register.


Ok, and then anything it cant place in a register, it puts on the stack?


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 22, 2022 11:49 am 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
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.

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.


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.

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 22, 2022 2:14 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
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.


Top
 Profile  
Reply with quote  
PostPosted: Sat Apr 30, 2022 9:35 pm 
Offline

Joined: Sun Oct 07, 2018 6:04 pm
Posts: 30
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.


Top
 Profile  
Reply with quote  
PostPosted: Sat Apr 30, 2022 9:41 pm 
Offline

Joined: Sun Oct 07, 2018 6:04 pm
Posts: 30
xlar54 wrote:

Ok, and then anything it cant place in a register, it puts on the stack?


Yes, any parameter that is not placed in a register is placed on the stack. For the 65816 it is the hardware stack and for the 6502 it uses a simulated stack that can be up to 64K (provided you have RAM and space for it).

Sorry for the late answer.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 82 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: