Compiling C and Assembly for Symon
Compiling C and Assembly for Symon
Hey guys,
Sorry if this question has been answered a million times before, but I've researched a bit and haven't been able to come up with anything, so sorry for asking.
I've done systems programming before (writing small test operating systems in x86 assembly and C) and I've written a small CPU emulator, so I'm not new to the concepts involved with the 6502 (or assembly language), however, compiling my code is my weakest point. At the moment, I'm kind of stuck on how to properly use the cc65 toolchain to compile for the Symon Emulator. I have a windows script that would generate a flat binary file that Symon would correctly load, however, I don't believe it compiles correctly.
The issue I'm having is the linker is telling me that __STARTUP__ (which I assume is the entrypoint for my code) is unresolved, and it cannot create my output file (I left main out of the code and created another function and everything worked well). I'm completely stumped by how to go about resolving this, and any help would be greatly appreciated.
I then tried compiling a basic assembly file as a .prg, but I also wasn't too sure how to do that either, so it comes down to me not really knowing how to compile and link.
Note that eventually, this code will be built for a custom target, so I don't know how that's going to affected..
Any help would be greatly appreciated, and sorry if I posted this into the wrong board!
-Quaker762
Sorry if this question has been answered a million times before, but I've researched a bit and haven't been able to come up with anything, so sorry for asking.
I've done systems programming before (writing small test operating systems in x86 assembly and C) and I've written a small CPU emulator, so I'm not new to the concepts involved with the 6502 (or assembly language), however, compiling my code is my weakest point. At the moment, I'm kind of stuck on how to properly use the cc65 toolchain to compile for the Symon Emulator. I have a windows script that would generate a flat binary file that Symon would correctly load, however, I don't believe it compiles correctly.
The issue I'm having is the linker is telling me that __STARTUP__ (which I assume is the entrypoint for my code) is unresolved, and it cannot create my output file (I left main out of the code and created another function and everything worked well). I'm completely stumped by how to go about resolving this, and any help would be greatly appreciated.
I then tried compiling a basic assembly file as a .prg, but I also wasn't too sure how to do that either, so it comes down to me not really knowing how to compile and link.
Note that eventually, this code will be built for a custom target, so I don't know how that's going to affected..
Any help would be greatly appreciated, and sorry if I posted this into the wrong board!
-Quaker762
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Compiling C and Assembly for Symon
Welcome, Quaker762.
I believe that you posted to the correct board, so rest assured that a qualified expert will be around shortly to help. Unfortunately, I'm not that expert ... I've only experimented very tentatively with cc65 myself, and I will be following this thread to hopefully have my (similar) questions answered as well.
Mike
I believe that you posted to the correct board, so rest assured that a qualified expert will be around shortly to help. Unfortunately, I'm not that expert ... I've only experimented very tentatively with cc65 myself, and I will be following this thread to hopefully have my (similar) questions answered as well.
Mike
Re: Compiling C and Assembly for Symon
The __STARTUP__ label originates in the crt0.s source file for your target. You get crt0.o after it's compiled and you include this as the FIRST file in your linker chain. I usually rename the crt0.o file to match my target, i.e. for my sbc4 target, it becomes sbc4.o.
I too use windows batch files. here's an example from one of my demo's:
where sbc4.cfg is the config file for my target, hello.65b is the executable object file, hello.map is a reference map file (not needed), sbc4.o is the crt0.o file, hello.s is the source of the program being executed, and sbc4.lib is the library file for my target.
hope that helps!
Daryl
I too use windows batch files. here's an example from one of my demo's:
Code: Select all
set CC65LIB=c:\cc65\lib
cl65 -t none -C sbc4.cfg -o hello.65b -m hello.map -l %CC65LIB%\sbc4.o hello.s %CC65LIB%\sbc4.lib
del *.o /Q >nul
pausehope that helps!
Daryl
Please visit my website -> https://sbc.rictor.org/
Re: Compiling C and Assembly for Symon
8BIT wrote:
The __STARTUP__ label originates in the crt0.s source file for your target. You get crt0.o after it's compiled and you include this as the FIRST file in your linker chain. I usually rename the crt0.o file to match my target, i.e. for my sbc4 target, it becomes sbc4.o.
I too use windows batch files. here's an example from one of my demo's:
where sbc4.cfg is the config file for my target, hello.65b is the executable object file, hello.map is a reference map file (not needed), sbc4.o is the crt0.o file, hello.s is the source of the program being executed, and sbc4.lib is the library file for my target.
hope that helps!
Daryl
I too use windows batch files. here's an example from one of my demo's:
Code: Select all
set CC65LIB=c:\cc65\lib
cl65 -t none -C sbc4.cfg -o hello.65b -m hello.map -l %CC65LIB%\sbc4.o hello.s %CC65LIB%\sbc4.lib
del *.o /Q >nul
pausehope that helps!
Daryl
I sort of understand what you mean, however my compiler isn't generating a crt0.s file for me. It might help if I show you how everything is structured:
In my directory, I have a file called kmain.c. This will be (hopefully) the main Kernel File for my OS. I then have a .cfg which consists of the following:
Code: Select all
MEMORY {
RAM1: start = $0200, size = $7F00;
ROM1: start = $C000, size = $4000, fill = yes;
}
SEGMENTS {
CODE: load = ROM1, type = ro;
DATA: load = ROM1, type = ro;
}
My kmain.c consists of the basic:
Code: Select all
int main()
{
return 0;
}
Code: Select all
SET PATH=%CC65_BIN%
REM COMPILE ALL C CODE IN .S FILES, BEFORE WE COMPILE AND THEN LINK THEM INTO A 16KB ALIGNED ROM
cc65 kmain.c -t none -Osir --cpu 6502
cl65 kmain.s -t none -C kern.cfg -o kern.bin
pause
ld65: Error: 1 unresolved external(s) found - cannot create output file
On further inspection of my kmain.s file, I found this,
Code: Select all
.forceimport __STARTUP__Seeing as there is no __STARTUP__ referenced ANYWHERE in my code, I'm still unsure how to resolve this.
Sorry for the lengthy post hahaha
-Quaker762
EDIT: Wait, is crt0.s meant to act as a bootloader?
Re: Compiling C and Assembly for Symon
You will need to use a library file to allow you to use any C code. your <main> right now is essential empty, but as soon as you start adding code, it will fail to link without a library file. Yes, the crt0.s is a sort of a bootloader...
Here's my crt0.s for the sbc4 target:
This might help you understand CC65 better:
http://cc65.github.io/cc65/doc/intro.html
Daryl
Here's my crt0.s for the sbc4 target:
Code: Select all
;
; Ullrich von Bassewitz, 17.06.1998
;
; Startup code for cc65
;
; This must be the *first* file on the linker command line
;
;
; Modified for SBC-4 by Daryl Rictor
;
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import __RAM_START__
.import initlib, donelib
.import callmain ;, callirq
.import zerobss ;, push0
; .import _main
.include "zeropage.inc"
.include "sbc4.inc"
;
; SBC-4 file format includes a 3 byte load address at the beginning of the file
; The EXEHDR segment places these three bytes at the beginning of the output file
;
.segment "EXEHDR"
.word __RAM_START__ ; Start address
.byte $00 ; bank 0
.segment "STARTUP"
; ------------------------------------------------------------------------
; Actual code
; Clear the BSS data
jsr zerobss
; setup the stack
lda #<TOPMEM
sta sp
lda #>TOPMEM
sta sp+1 ; Set argument stack ptr
; Call module contructors
jsr initlib
; Push arguments and call main
jsr callmain
; Call module destructors. This is also the _exit entry.
_exit:
jsr donelib
jmp _osreturn ; SBC-4 DiskOS re-entry point
.bss
hicol: .res 1
locol: .res 1
curs: .res 1
http://cc65.github.io/cc65/doc/intro.html
Daryl
Please visit my website -> https://sbc.rictor.org/
Re: Compiling C and Assembly for Symon
Hi again,
I just stumbled upon how to create a custom target in the cc65 tutorial, so I have a correct library file, however I'm still getting some bizarre issues that I don't think I should be getting. I'm using the default crt0.s file as specified at:
http://www.cc65.org/doc/customizing-3.html,
and so have modified my linker cfg to better suit this code:
However I still get Unresolved externals, which if I've followed the tutorial correctly, shouldn't be happening.
I'm sure it's merely errors in my linker file, as the errors I'm getting are:
I'm confused, as __RAM_START__ and __RAM_SIZE__ should apparently be generated by the linker. Anything to do with __DATA_ seems to be related to the copydata import
I commented out the offending lines (just to test if it would even load in the emulator) and managed to get a compiled binary file, however I got no code execution whatsoever. The PC just incremented every step while giving me a BRK instruction.
I'm even more confused now, and have no idea what to do anymore
Again, sorry for asking such mundane questions.
-Quaker762
I just stumbled upon how to create a custom target in the cc65 tutorial, so I have a correct library file, however I'm still getting some bizarre issues that I don't think I should be getting. I'm using the default crt0.s file as specified at:
http://www.cc65.org/doc/customizing-3.html,
and so have modified my linker cfg to better suit this code:
Code: Select all
MEMORY {
ZP: start = $0, size = $100, type = rw, define = yes;
RAM: start = $0200, size = $7F00;
ROM: start = $C000, size = $4000, fill = yes;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
STARTUP: load = ROM, type = ro;
INIT: load = ROM, type = ro;
CODE: load = ROM, type = ro;
DATA: load = ROM, type = rw;
BSS: load = RAM, type = bss, define = yes;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
I'm sure it's merely errors in my linker file, as the errors I'm getting are:
Code: Select all
Unresolved external `__DATA_LOAD__' referenced in:
common/copydata.s(13)
common/copydata.s(15)
Unresolved external `__DATA_RUN__' referenced in:
common/copydata.s(18)
common/copydata.s(20)
Unresolved external `__DATA_SIZE__' referenced in:
common/copydata.s(23)
common/copydata.s(24)
Unresolved external `__RAM_SIZE__' referenced in:
crt0.s(32)
crt0.s(34)
Unresolved external `__RAM_START__' referenced in:
crt0.s(32)
crt0.s(34)
I commented out the offending lines (just to test if it would even load in the emulator) and managed to get a compiled binary file, however I got no code execution whatsoever. The PC just incremented every step while giving me a BRK instruction.
I'm even more confused now, and have no idea what to do anymore
Again, sorry for asking such mundane questions.
-Quaker762
Re: Compiling C and Assembly for Symon
You are making progress!
Can you post your batch file? It should have also changed to include your target library and crt0.o file.
Don't worry about the questions... I had similar struggles when I started using CC65.
Daryl
Can you post your batch file? It should have also changed to include your target library and crt0.o file.
Don't worry about the questions... I had similar struggles when I started using CC65.
Daryl
Please visit my website -> https://sbc.rictor.org/
Re: Compiling C and Assembly for Symon
Okay, here's my batch files.
I have two, but I'll put them into one eventually:
BuildLib.bat
dos.lib is copied and renamed from cc65/lib/supervision.lib as recommended in the tutorial.
Build.bat
Sort of spaghetti code, it'll get cleaned eventually ahaha.
I have two, but I'll put them into one eventually:
BuildLib.bat
Code: Select all
@ECHO off
SET CC65_BIN=E:\Users\Jesse\Documents\System I\cc65\bin
SET PATH=%CC65_BIN%
ca65 --cpu 6502 crt0.s
ar65 a dos.lib crt0.o
pause
Build.bat
Code: Select all
@ECHO off
SETLOCAL
REM SET OUR CC65 ENV VARIABLES
SET CC65_HOME=E:\Users\Jesse\Documents\System I\cc65
SET CC65_INC=E:\Users\Jesse\Documents\System I\cc65\asminc
SET CC65_BIN=E:\Users\Jesse\Documents\System I\cc65\bin
SET LD65_LIB=E:\Users\Jesse\Documents\System I\cc65\lib
SET PATH=%CC65_BIN%
REM COMPILE ALL C CODE IN .S FILES, BEFORE WE COMPILE AND THEN LINK THEM INTO A 16KB ALIGNED ROM
cc65 -t none --cpu 6502 kmain.c
ca65 kmain.s
ld65 -C symon.cfg -o kernel.bin -m kern.map -vm kmain.o dos.lib
GOTO CLEAN
:CLEAN
REM DELETE ALL OF OUR .O FILES
DEL /S *.o
GOTO PAUSE
:PAUSE
pause
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Compiling C and Assembly for Symon
Space char(s) in your pathname? Bill Buckels mentions that as a no-no in the thread referenced below. Could it be something that simple?
https://groups.google.com/forum/#!searc ... 8D5fEWchQJ
Mike
https://groups.google.com/forum/#!searc ... 8D5fEWchQJ
Mike
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Compiling C and Assembly for Symon
Quaker762 wrote:
Code: Select all
@ECHO off
SET CC65_BIN=E:\Users\Jesse\Documents[b]\System I\[/b]cc65\bin
SET PATH=%CC65_BIN%
ca65 --cpu 6502 crt0.s
ar65 a dos.lib crt0.o
pause
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: Compiling C and Assembly for Symon
In your second batch file, change this line:
to this:
Be sure the crt0.o is in one of the paths. This is how I got my code to compile. I'm not sure its right, but it did work for me.
Daryl
Code: Select all
ld65 -C symon.cfg -o kernel.bin -m kern.map -vm kmain.o dos.lib Code: Select all
ld65 -C symon.cfg -o kernel.bin -m kern.map -vm crt0.o kmain.o dos.lib Daryl
Please visit my website -> https://sbc.rictor.org/
Re: Compiling C and Assembly for Symon
barrym95838 wrote:
Space char(s) in your pathname?
BigDumbDinosaur wrote:
Use of whitespace in filenames is generally considered to be bad practice, especially in a compiler "make file." Unfortunately, MS Windows actively promotes that sort of thing.
8BIT wrote:
In your second batch file, change this line:
to this:
Be sure the crt0.o is in one of the paths. This is how I got my code to compile. I'm not sure its right, but it did work for me.
Daryl
Code: Select all
ld65 -C symon.cfg -o kernel.bin -m kern.map -vm kmain.o dos.lib Code: Select all
ld65 -C symon.cfg -o kernel.bin -m kern.map -vm crt0.o kmain.o dos.lib Daryl
http://imgur.com/XZuQOfQ
I'm putting it down to something missing from my linker script, but again, the RAM symbols should be generated by the linker.
-Quaker762
Re: Compiling C and Assembly for Symon
I'll try to dust off my cc65 this weekend and see if I can duplicate the problem based on your files. Then I might be able to resolve it.
Daryl
Daryl
Please visit my website -> https://sbc.rictor.org/
Re: Compiling C and Assembly for Symon
8BIT wrote:
I'll try to dust off my cc65 this weekend and see if I can duplicate the problem based on your files. Then I might be able to resolve it.
Daryl
Daryl
kmain.c
Code: Select all
int main()
{
int x = 0;
int i;
for(i = 0; i < 1000; i++)
{
x = x + 1;
}
for(;;);
return 0;
}
Code: Select all
; ---------------------------------------------------------------------------
; crt0.s
; ---------------------------------------------------------------------------
;
; Startup code for cc65 (Single Board Computer version)
.export _init, _exit
.import _main
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import __RAM_START__, __RAM_SIZE__ ; Linker generated
.import copydata, zerobss, initlib, donelib
.include "zeropage.inc"
; ---------------------------------------------------------------------------
; Place the startup code in a special segment
.segment "STARTUP"
; ---------------------------------------------------------------------------
; A little light 6502 housekeeping
_init: LDX #$FF ; Initialize stack pointer to $01FF
TXS
CLD ; Clear decimal mode
; ---------------------------------------------------------------------------
; Set cc65 argument stack pointer
LDA #<(__RAM_START__ + __RAM_SIZE__)
STA sp
LDA #>(__RAM_START__ + __RAM_SIZE__)
STA sp+1
; ---------------------------------------------------------------------------
; Initialize memory storage
JSR zerobss ; Clear BSS segment
JSR copydata ; Initialize DATA segment
JSR initlib ; Run constructors
; ---------------------------------------------------------------------------
; Call main()
JSR _main
; ---------------------------------------------------------------------------
; Back from main (this is also the _exit entry): force a software break
_exit: JSR donelib ; Run destructors
BRK
Re: Compiling C and Assembly for Symon
ok - found some time today.
This worked for me. edit your .cfg file to this:
I added the to the lines that were unresolved.
Give that a try.
Daryl
This worked for me. edit your .cfg file to this:
Code: Select all
MEMORY {
ZP: start = $0, size = $100, type = rw, define = yes;
RAM: start = $0200, size = $7F00, define = yes;
ROM: start = $C000, size = $4000, fill = yes;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
STARTUP: load = ROM, type = ro, define = yes;
INIT: load = ROM, type = ro, define = yes;
CODE: load = ROM, type = ro, define = yes;
DATA: load = ROM, type = rw, define = yes;
BSS: load = RAM, type = bss, define = yes;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}Code: Select all
, define = yesGive that a try.
Daryl
Please visit my website -> https://sbc.rictor.org/