How do I get CC65 to include NO startup code?

You need an actual VIC.

Moderator: Moderators

JavaJack59
Vic 20 Newbie
Posts: 11
Joined: Thu Jun 05, 2014 1:55 pm

How do I get CC65 to include NO startup code?

Post by JavaJack59 »

I'm trying to write a simple C program that does nothing more than poking graphics characters to the screen, like:

Code: Select all

void main (void) {
    unsigned char *screen       = (unsigned char *)7680;
    screen[0] = 81; // petscii ball character in upper left
}
How do I get cc65 to put NO startup code in this program? I don't want lowercase since I'm using graphic characters, I don't need params passed to main, I don't need to return to basic afterwards, etc. I just want to throw some characters onto the screen and nothing else.
User avatar
Mike
Herr VC
Posts: 4832
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: How do I get CC65 to include NO startup code?

Post by Mike »

First of all, welcome to Denial! :)

To your question:
JavaJack59 wrote:I don't need params passed to main
I'm sorry, but I need to be nitpicky quite at this stage already. The C standard says there are two valid prototypes for main():

Code: Select all

int main(void);
int main(int argc, char* argv[]);
... which mean, either take no arguments at all, or pass arguments from the command line. There is no 'void main(void)' in this list.

That being said, you'd need to recompile cc65 and reassemble the startup stub to roughly get what you want. But even with that proviso, you probably won't get anything like:

Code: Select all

 LDA #$51
 STA $1E00
 [...]
as result. Your C fragment would create the variable 'screen' on the stack and copy it to the zeropage to make it available as pointer for the (ZP),Y addressing mode. You'd still need a BASIC stub, so the program can be executed with RUN. Finally, per default, the ball would appear in white on white background as you didn't write to the colour RAM as well.

I suppose ca65 is more the right tool for the job. There, you can include a minimal BASIC stub as you need it, and then write the necessary 3 (or 5) lines of assembly code to do the task.

Greetings,

Michael
JavaJack59
Vic 20 Newbie
Posts: 11
Joined: Thu Jun 05, 2014 1:55 pm

Re: How do I get CC65 to include NO startup code?

Post by JavaJack59 »

Mike wrote:First of all, welcome to Denial! :)
Thanks :)
Mike wrote:you'd need to recompile cc65 and reassemble the startup stub
Hmm. Was there a good rationale for making this a recompile issue for the compiler itself, rather than using an .asm file for the startup code and assembling it at compile time? I'm no expert, but this seems... odd. Or I'm misunderstanding your comment.
Mike wrote:Your C fragment would create the variable 'screen' on the stack and copy it to the zeropage to make it available as pointer for the (ZP),Y addressing mode.
That's perfectly acceptable for my use case. The actual program would make use of for/if/while and arrays. And yeah, I was already aware of the color thing.
Mike wrote:I suppose ca65 is more the right tool for the job.
Only if I want a 20-fold increase in development time, since I've never written more than 3 or 4 lines of 6502.
User avatar
Mike
Herr VC
Posts: 4832
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: How do I get CC65 to include NO startup code?

Post by Mike »

Mike wrote:you'd need to recompile cc65 and reassemble the startup stub
JavaJack59 wrote:Hmm. Was there a good rationale for making this a recompile issue for the compiler itself, rather than using an .asm file for the startup code and assembling it at compile time? I'm no expert, but this seems... odd. Or I'm misunderstanding your comment.
O.K., maybe not quite recompiling cc65 itself, but the relevant *.s file is usually not re-assembled at compile time, neither. Normally, a cc65 installation would refer to 'vic20.lib' as soon as you're going to build anything for the VIC-20. That library contains a collection of pre-assembled *.s and pre-compiled *.c files for the runtime and C library.

The *.s file you'd have to take a deeper look into is 'crt0.s':

- it copies the current ZP contents to a save place,
- switches the character set to lower case (what you where complaining about),
- clears the BSS data,
- initialises the stack,
- calls an init function (...),
- calls main(),
- calls a function to close the lib (i.e. cleanup),
- restores the old ZP contents, and
- finally places the return code in the status variable ST.

Whatever you have in mind changing about 'crt0.s', you'll have to recompile a new 'vic20.lib' from the source tree - possibly excluding the whole standard library as I see you don't want to use it. And then you can try stripping off initlib() and other function calls in crt0.s and see how far it goes ...
Only if I want a 20-fold increase in development time, since I've never written more than 3 or 4 lines of 6502.
Thus far you didn't tell what you are up to. That stripped down C dialect that you're going to use won't be nearly as efficient as machine language on the 6502, and you will miss out those routines in the C library that actually have been crafted in machine code (using ca65) instead of being compiled from C source.

And as there's no direct equivalent to the processor registers in C, without having the proper veneers in the library you can pretty much forget using any routines of the BASIC and KERNAL ROMs.
JavaJack59
Vic 20 Newbie
Posts: 11
Joined: Thu Jun 05, 2014 1:55 pm

Re: How do I get CC65 to include NO startup code?

Post by JavaJack59 »

Mike wrote:Thus far you didn't tell what you are up to.
A digital clock program. Read the jiffy clock and display it as large fixed petscii-art digits. The digits themselves wouldn't even need to change. Segments would be turned on/off by updating color RAM.
User avatar
Mike
Herr VC
Posts: 4832
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: How do I get CC65 to include NO startup code?

Post by Mike »

JavaJack59 wrote:A digital clock program. Read the jiffy clock and display it [...]
In that case, the thread 'Display of TI$ in border (unex. or +3K)' might be worth a look. :wink:
groepaz
Vic 20 Scientist
Posts: 1185
Joined: Wed Aug 25, 2010 5:30 pm

Re: How do I get CC65 to include NO startup code?

Post by groepaz »

technically, you dont need to recompile anything, just use -t none for no startup code and instead of main() use start():

Code: Select all

$ cat test.c
void start(void)
{
    asm("inc $d020");
}
$ cl65 -o test.bin -t none test.c
$ hex test.bin
0000  ee 20 d0 60
(mind you, a lot of the C language relies on the startup code, so you better know what you are doing... at least properly set up the pointers to the software stack and heap. perhaps you also want a basic stub so you dont need to run the binary by SYS. and add a proper CBM load address to the output. etc etc :))
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
JavaJack59
Vic 20 Newbie
Posts: 11
Joined: Thu Jun 05, 2014 1:55 pm

Re: How do I get CC65 to include NO startup code?

Post by JavaJack59 »

groepaz wrote:just use -t none for no startup code and instead of main() use start():
That looked promising, but I just ended up with a bunch of "Unresolved external" errors.
I also briefly tried Quetzalcoatl for comparison, and it wouldn't build either ("Could not find runtime library uplrtime.obj")
Guess it's back to BASIC or klutzing my way through assembly.
User avatar
Misfit
Vic 20 Devotee
Posts: 207
Joined: Thu Nov 28, 2013 9:09 am

Re: How do I get CC65 to include NO startup code?

Post by Misfit »

Hi,

I use CC65 for VIC games and here is my simple cc65 project skeleton (unexpanded vic):

crt0.s:

Code: Select all

.import   _main
.import   __RAM_START__, __RAM_SIZE__	; Linker generated
.export   __STARTUP__ : absolute = 1    ; Mark as startup
.include  "zeropage.inc"

.segment "STARTUP"
.word $1001; Load address
.byte $0B, $10, $00, $00, $9E, '4','1','0','9',$00, $00, $00

lda #<(__RAM_START__ + __RAM_SIZE__)
sta sp
lda #>(__RAM_START__ + __RAM_SIZE__)
sta sp+1
jsr _main
..and main.c:

Code: Select all

typedef unsigned char byte;

#define SCREEN_ADDR   (0x1E00)
#define COL_ADDR      (0x9600)

byte* ptr_screen;
byte* ptr_color;

void main()
{
    ptr_screen = SCREEN_ADDR;
    ptr_color = COL_ADDR;
    
    ptr_screen[1] = 0x01;
    ptr_color[1] = 0x02;
    
    ptr_screen[2] = 0x02;
    ptr_color[2] = 0x03;

    loop:
    goto loop;
}
User avatar
Mike
Herr VC
Posts: 4832
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: How do I get CC65 to include NO startup code?

Post by Mike »

Misfit, your example is missing the necessary *.cfg file for the unexpanded VIC-20. It would also have been nice to provide a make file.

Nonetheless, I ran main.c through cc65 with '-t none', with this result (sorry for this slightly longer listing ...):

Code: Select all

;
; File generated by cc65 v 2.13.2
;
	.fopt		compiler,"cc65 v 2.13.2"
	.setcpu		"6502"
	.smart		on
	.autoimport	on
	.case		on
	.debuginfo	off
	.importzp	sp, sreg, regsave, regbank, tmp1, ptr1, ptr2
	.macpack	longbranch
	.forceimport	__STARTUP__
	.export		_ptr_screen
	.export		_ptr_color
	.export		_main

.segment	"BSS"

_ptr_screen:
	.res	2,$00
_ptr_color:
	.res	2,$00

; ---------------------------------------------------------------
; void __near__ main (void)
; ---------------------------------------------------------------

.segment	"CODE"

.proc	_main: near

.segment	"CODE"

	ldx     #$1E
	lda     #$00
	sta     _ptr_screen
	stx     _ptr_screen+1
	ldx     #$96
	lda     #$00
	sta     _ptr_color
	stx     _ptr_color+1
	lda     _ptr_screen
	ldx     _ptr_screen+1
	jsr     pushax
	ldx     #$00
	lda     #$01
	ldy     #$01
	jsr     staspidx
	lda     _ptr_color
	ldx     _ptr_color+1
	jsr     pushax
	ldx     #$00
	lda     #$02
	ldy     #$01
	jsr     staspidx
	lda     _ptr_screen
	ldx     _ptr_screen+1
	jsr     pushax
	ldx     #$00
	lda     #$02
	ldy     #$02
	jsr     staspidx
	lda     _ptr_color
	ldx     _ptr_color+1
	jsr     pushax
	ldx     #$00
	lda     #$03
	ldy     #$02
	jsr     staspidx
L0015:	jmp     L0015
	rts

.endproc
Dumbing down cc65 for this kind of use is really like using a hammer to turn a screw.

The equivalent assembly code (excluding the BASIC stub) would only use 4 LDAs and 4 STAs.

Well, you got 'Bertie the Ball' built and working with that method, but that verbose code above makes me wonder if it had been possible to pack the game into just +8K RAM instead (or providing more screens) - with pure assembly.

The lesson for me: it is actually possible to use cc65 in the way asked for in the OP. Not that I would want to use it like that, though.

<fx=goes off the stage></fx>
JavaJack59
Vic 20 Newbie
Posts: 11
Joined: Thu Jun 05, 2014 1:55 pm

Re: How do I get CC65 to include NO startup code?

Post by JavaJack59 »

Mike wrote:missing the necessary *.cfg file
Yeah. I ended up with this:

Code: Select all

E:\coding\cc65\min>ld65 main.o vic20_minimal.o
ld65: Error: Memory configuration missing
User avatar
Misfit
Vic 20 Devotee
Posts: 207
Joined: Thu Nov 28, 2013 9:09 am

Re: How do I get CC65 to include NO startup code?

Post by Misfit »

project files

of course pure assembly code makes a smaller program, but I'm too lazy to create whole game without C-language.
Sometimes it's better to use more memory if it is the only way to create a finished product.
JavaJack59
Vic 20 Newbie
Posts: 11
Joined: Thu Jun 05, 2014 1:55 pm

Re: How do I get CC65 to include NO startup code?

Post by JavaJack59 »

Misfit wrote:project files
PERFECT.
For the uninitiated (read: me) what's the purpose of the "fill=yes" for "RAM" in the .cfg? I tried "fill=no" just to see what would happen and it seemed to work anyway.
Misfit wrote:Sometimes it's better to use more memory if it is the only way to create a finished product.
Agreed.
JavaJack59
Vic 20 Newbie
Posts: 11
Joined: Thu Jun 05, 2014 1:55 pm

Re: How do I get CC65 to include NO startup code?

Post by JavaJack59 »

Off to a decent start. Even pulling in memset and memcpy, I'm still under .5KB.

Image
groepaz
Vic 20 Scientist
Posts: 1185
Joined: Wed Aug 25, 2010 5:30 pm

Re: How do I get CC65 to include NO startup code?

Post by groepaz »

Dumbing down cc65 for this kind of use is really like using a hammer to turn a screw.
not really. he made a small crt0 which basically removes the heap, and doesnt use the interrupt chain stuff. both of which you dont want to use in a memory constrained environment anyway - i have done the same for all c64 programs i made with cc65.
The equivalent assembly code (excluding the BASIC stub) would only use 4 LDAs and 4 STAs.
try with -Osir :) the generated code is large in some cases, but its not *that* bad really :)
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
Post Reply