Jump to content
IGNORED

cc65 and page zero abuse.. any workaround?


xt5

Recommended Posts

hi,

 

this is my first post here, Im really new to the atari world, just got my first ever atari just 2 weeks ago :)

 

I've playing a little with cc65, the assembler and linker seems really good, but I've lot of problems with the compiler generated code.

 

first, I don't like to use page zero at all for temporal values and pointers, that is why I've done my own linker scripts and generate a nice exe without use the atari libs of the cc65 package :)

 

for example a simple code like this:

 

unsigned char data[211] = {
0x4A, 0x55, 0x45, 0x47, 0x4F, 0x31, 0x20, 0x44, 0x46, 0x53, 0x46, 0x00, 0x4A, 0x55, 0x45, 0x47, 
	..................................
	......................
	..............
0x31, 0x37, 0x00
}; // global

unsigned char i; // global

......
..

for(i=0; i<sizeof(data); i++) data[i]-=0x20;

 

generate a very big and slow code that uses a page zero pointer, the code generated is

 

	lda	 #$00
L0147:	sta	 _i
cmp	 #$D3
bcs	 L0122
lda	 #<(_data)
ldx	 #>(_data)
clc
adc	 _i
bcc	 L012C
inx
L012C:	sta	 ptr1
stx	 ptr1+1
ldy	 #$00
lda	 (ptr1),y
sec
sbc	 #$20
sta	 (ptr1),y
lda	 _i
clc
adc	 #$01
jmp	 L0147

 

the same code is generated either with -O, -Oi, -Or, -Os, -Oir, -Ois, -Ors

 

the code without optimization is even worse:

 

L0121:	ldx	 #$00
lda	 _i
cmp	 #$D3
jsr	 boolult
jne	 L0124
jmp	 L0122
L0124:	lda	 #<(_data)
ldx	 #>(_data)
clc
adc	 _i
bcc	 L012C
inx
L012C:	jsr	 pushax
ldy	 #$00
jsr	 ldauidx
sec
sbc	 #$20
ldy	 #$00
jsr	 staspidx
ldx	 #$00
lda	 _i
pha
clc
adc	 #$01
sta	 _i
pla
jmp	 L0121
L0122:

 

so Im very disappointed with this, as I've to tweak 50% of the code generated, maybe Im just missing something :( because the code you would expect by that simple snippet is something that just avoid page zero *abuse* like this

 

	ldy	 #$00	

loop:	
cpy	 #$D3
bcs	 L0130

lda	 _data,y
sec
sbc	 #$20
sta	 _data,y	
iny
jmp	 loop

 

that seems to be a very common issue on 6502 compilers as I've tested IAR one and seems also abuse zero page, also I've tested other one (can't remeber the name) and was even worse..

 

please give me any direction in this fun atari coding thing :)

 

regards,

xt5

Link to comment
Share on other sites

i love the "i++" and "lda i, clc, adc #1" one... ;)

 

no kidding... I am a pure assembler fan so I have no clue regarding cc65.... but here are Wrathchild, Bryan etc who use cc65...they should be able to help a little bit...

 

but in general compiler can not be as good as a hand optimised code... f.e. how should cc65 know that you won't use (zp),y but absolute instead? for the compiler it is the same?

Link to comment
Share on other sites

Couldn't you just have a series of TEMPn type variables.

 

Then when you want to use them as pointers, just assign them the value needed?

 

Another pure Asm fan here - personally I don't see a lot of point using mid-level languages on machines with such small amounts of RAM.

Link to comment
Share on other sites

Welcome,

 

some remarks for you:

 

  • I would address this problem to the mailing list of CC65. Uz is very kind and responsive and many other CC65 experts are subscribed to the list too
  • the 'clc,adc #$01' thing could be an improvement for the peephole optimizer - a perfect disscussion entry for the list
  • of course you can use the inline assembler when performing such tasks or write your own assembler function, retrieving address, size and operation...
  • the code is so bad since CC65 has to cover many use cases, sizes of datatypes etc. and it generates general code patterns for the operations

 

Another pure Asm fan here - personally I don't see a lot of point using mid-level languages on machines with such small amounts of RAM.

 

I think it is better than using Basic: You can better connect high-level-code to assemby-code (which you need anyhow for 'impressive'-results) and it is faster. Also the maintainability is much better. It would have been no fun and longer job to write the IO and highscore-entry management (sorting) in ECKN in assembly language.

 

CU

Irgendwer

Edited by Irgendwer
Link to comment
Share on other sites

Hiya,

this was discussed on the CC65 mailing list, and the solution is to use ++i in the for loop. i++ is an expression that returns a value, and then increments i, which is why the weird code is generated. With ++i the code becomes:

 

;
; for(i = 0; i < sizeof(data); ++i) {
;
	lda	 #$00
	sta	 _i
L0017:  lda	 _i
	cmp	 #$D3
	bcs	 L0018
; 
; data[i] -= 0x20;
;	   
	lda	 #<(_data)
	ldx	 #>(_data)
	clc	 
	adc	 _i
	bcc	 L0022
	inx	 
L0022:  sta	 ptr1
	stx	 ptr1+1
	ldy	 #$00
	lda	 (ptr1),y
	sec	 
	sbc	 #$20
	sta	 (ptr1),y
; 
; for(i = 0; i < sizeof(data); ++i) {
;	   
	inc	 _i
	jmp	 L0017
; 
; }
;
L0018:  rts

 

You still get slightly convoluted code for the array code, as C uses ints for array indexing, which won't fit in the Y register. The compiler will never match the speed and size of handwritten 6502 assembler, so enjoy the faster development and better maintainability of the main code, and leave the speed critical parts in assembler (which is easy to call from C).

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...