Hi everyone, i've been struggling with CC65, and i think it's finally time to just go online and ask for help.
I once got to the point where it was actually able to output a binary, but i had to start from scratch... so i don't even have that anymore.
I'm running on Windows so i'm using the the Snapshot ZIP that has everything pre-compiled.
I added "CC65\bin" to PATH and also added new variables for "CC65_HOME", "CC65_BIN", "CC65_INC", and "LD65_LIB" which are all pointing to the correct folders.
I somewhat loosely followed the tutorial on here:
https://cc65.github.io/doc/customizing.html"loosely" because obviously the Memory Map is different and because the Interrupt vectors cannot be changed in my SBC, so the "vectors.s" file and the "VECTORS" Segment were unnecessary.
So my setup looks like this right now:
"SBC.cfg" has this in it:
Code:
#
# Proxy's 65C02 SBC v2
#
# Memory Map:
# 0x0000 - 0xF6FF - RAM (61.75kB)
# 0xF700 - 0xF7FF - IO ( 0.25kB)
# 0xF800 - 0xFFFF - ROM ( 2.00kB)
#
# some ZP is used for the ROM, so start 32B into ZP
MEMORY {
ZP: start = $0020, size = $00E0, type = rw, define = yes;
RAM: start = $0200, size = $F500, type = rw, define = yes;
IO: start = $F700, size = $0100, type = rw, define = yes;
ROM: start = $F800, size = $0800, type = ro, define = yes;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = RAM, type = rw, define = yes;
BSS: load = RAM, type = bss, define = yes;
HEAP: load = RAM, type = bss, optional = yes;
STARTUP: load = RAM, type = ro;
ONCE: load = RAM, type = ro, optional = yes;
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
# Define the Stack Size (4kB) for the Program
__STACKSIZE__: value = $1000, type = weak;
}
my "crt0.s", which like the Tutorial i put into a copy of the Supervison's .lib file, looks like this:
Code:
; ---------------------------------------------------------------------------
; crt0.s
; ---------------------------------------------------------------------------
;
; Startup code for cc65 (Proxy SBC v2)
.export _init, _exit
.import _main, _brk_isr, _irq_isr, _nmi_isr
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import __RAM_START__, __RAM_SIZE__ ; Linker generated
.import copydata, zerobss, initlib, donelib
.include "zeropage.inc"
.PC02 ; Force 65C02 assembly mode
; ---------------------------------------------------------------------------
; Place the startup code in a special segment
.segment "STARTUP"
; ---------------------------------------------------------------------------
; Set up the Stack and some Flags
_init:
LDX #$FF
TXS ; Initialize stack pointer to 0xFF
CLD ; Disable BCD Mode
SEI ; Disable Interrupts
; ---------------------------------------------------------------------------
; Set CC65 argument stack pointer
LDA #<(__RAM_START__ + __RAM_SIZE__)
LDX #>(__RAM_START__ + __RAM_SIZE__)
STA sp
STX sp+1
; ---------------------------------------------------------------------------
; Initialize memory storage
JSR zerobss ; Clear BSS segment
;JSR copydata ; Initialize DATA segment, any reason for this? since Data will be in RAM anyways...
JSR initlib ; Run constructors
; ---------------------------------------------------------------------------
; Set up the Interrupt Vectors in ZP, as the ROM redirects all Interrupts to these
LDA #>_brk_isr
LDX #<_brk_isr
STA $00
STX $01
LDA #>_irq_isr
LDX #<_irq_isr
STA $02
STX $03
LDA #>_nmi_isr
LDX #<_nmi_isr
STA $04
STX $05
; ---------------------------------------------------------------------------
; Call main()
JSR _main
; ---------------------------------------------------------------------------
; Back from main (this is also the _exit entry)
_exit:
JSR donelib ; Run destructors
JMP ($FFF8) ; Indirectly Jump to the Termination Function in ROM
the "Interrupt.s" file is pretty barren right now, for "i first want to get this running" reasons:
Code:
; ---------------------------------------------------------------------------
; Interrupt.s
; ---------------------------------------------------------------------------
;
; Interrupt handler
;
.export _brk_isr, _irq_isr, _nmi_isr
.segment "CODE"
.PC02 ; Force 65C02 assembly mode
; ---------------------------------------------------------------------------
; Break (BRK) Service Routine
_brk_isr:
NOP
RTI
; ---------------------------------------------------------------------------
; Interrupt (IRQ) Service Routine
_irq_isr:
NOP
RTI
; ---------------------------------------------------------------------------
; Non-Maskable Interrupt (NMI) Service Routine
_nmi_isr:
NOP
RTI
and finally the C source file called "test.c" has this:
Code:
#include <stdint.h>
int main(){
uint8_t T = 0;
uint8_t i;
for ( i = 0; i < 70; i++) {
T = (T << 1) ^ (i + T); // Just something to get the Compiler working :p
}
return 0;
}
on a side note it's kinda annoying how this compiles fine:
Code:
uint8_t i;
for (i = 0; i < 70; i++) {}
But this doesn't:
Code:
for (uint8_t i = 0; i < 70; i++) {}
like why?
anyways, I threw the "crt0.s" into the renamed "SBC.lib" file with these commands:
Code:
CA65 --cpu 65C02 -i crt0.s
AR65 r SBC.lib crt0.o
and then i try to Compile, Assemble, and Link everything else.
I split everything into seperate folders so i can order it better:
"Temp" is used to contain temporary files that are supposed to get deleted after successfully linking everything
"Config" holds the .cfg and .lib files, and "crt0.s"
"Include" has the "Interrupt.s" file and in the future various hardware drivers.
Code:
CC65 -t none -O --cpu 65C02 -o Temp\test.s test.c
CA65 --cpu 65C02 -o Temp\test.o Temp\test.s
LD65 -C Config\SBC.cfg -m main.map -v Include\Interrupt.o Temp\test.o Config\SBC.lib
but at this point the Linker is always just throwing "Unresolved External" Errors, with my old setup it would always throw those errors when i include some hardware drivers, but now it's also throwing them from things that should be working on their own:
Code:
crt0.s:75: Error: Unresolved external 'DONELIB'
crt0.s:46: Error: Unresolved external 'INITLIB'
crt0.s:38: Error: Unresolved external 'SP'
crt0.s:39: Error: Unresolved external 'SP'
crt0.s:44: Error: Unresolved external 'ZEROBSS'
crt0.s:69: Error: Unresolved external '_MAIN'
LD65: Error: 5 unresolved external(s) found - cannot create output file
to me this sounds like it cannot link crt0.o to test.o, but why? the PATHs are correct, and i gave it all the files it should (hopefully) need in the same order as the tutorial.
So what am i missing?
I added a zip file containing everything i made so far.