Conversation

#6502 question. Is there any sane and quick way way to do the equivalent of popping the return address grabbing the word after, calling it as a subroutine and then returning after the value ?
The more I look the more it seems that the 6502 way to do this is going to be to have tiny stub routines in common space for each banked function I would need to call instead.

Embarrasingly for the 6502 it seems even the TMS7000 has better code density for C programs at this point 8)

2
0
1

@etchedpixels If you have the CMOS variant, X-indexed JMP is available, e.g. JMP (&103,X), and that opens up some possibilities.

1
0
0

@pndc Alas I can't rely on 65C02 so I was guessing I'll end up with

stub_funcname:
LDA bankreg
PHA
LDA
STA bankreg
JSR _funcname
TAY
PLA
STA bankreg
TYA
RTS

or similar (obviously they can all share the last 5 instructions via a JMP if I wanted to squeeze a bit)

0
0
0
@etchedpixels Wait... C on 6502... how? Stack is limited to 256 bytes, and there's no reasonable way to do local variables, AFAICT. So... how does that work (without 10x slowdown)?
1
0
0

@pavel you have a separate C stack off a zero page pointer and Y, then track the Y register. I claim no credit here, CC65 figured that out I just copied their scheme.

So a local is something like

LDA (sp),Y
TAX
DEY
LDA (sp),Y

and for byte stuff especially you can do a lot of

ADC (@sp),Y

type things to directly use locals.

It does make stacking/unstacking a bit ugly on function calls but the local frames and arg access are fine.

It's not like Z80 or 8080 are better

2
1
0

@pavel Z80 you end up doing stuff like using IX and doing LD L(IX+3) LD H,(IX+2) which is less instructions but they take way more clocks than the 6502, and if you want to do a 16bit add of a value indexed off IX it's a total mess.

Compare to the lovely 6803 and

TSX
ADDD offset,X

1
0
0
@etchedpixels Yeah, my impression was that you can actually do C (and relocatable code) on 6800. I'm not too familiar with Z80.
1
0
0

@pavel I've retargetted one C compiler to 6800 and I've written a second. zu2 has ported a couple more.

You can do C on a 6800. The code density isn't great but I have an entire Unix clone running on my 6808 (6800 with standard 5v only and clocks etc) quite happily. 6803 is much nicer, 6303 is a bit nicer still, HC11 a tiny bit more, and 6809 is really nice.

0
0
1
@etchedpixels @sp Ok, clever, so it is doable without disallowing recursion or something like that. But penalty for running "normal" C code will still be high due to use of pointers, etc...?
1
0
0

@pavel Nope 6800 is fine. You've got indexed off the X register so you just track X carefully. Locals are generally stuff like

TSX (if needed)
ADDB n+1,x
ADCA n,x

And the only other trick is knowing that whilst 6800 lacks PULX you can do TSX LDX ,X INS INS instead

No tricks involved, it's running things like the genuine Bourne shell

1
0
1
@etchedpixels Ah, I see 6800 is fine. I was thinking about 6502. Bourne shell would be fun to fit there, no?

I mean, simple stuff like while (*dst++ = *src++) ; will be a lot of fun to compile for 6502...
1
0
0

@pavel Yes - mind you its messy on a lot of 8bit processors eg 6800/3 only has a single index register.

One of the things that cc65 shows nicely though is that a lot of the code you are executing is in the C library so if you make the hot parts of that asm (especially the tricky ones), you actually get really good performance.

0
0
1