Quantcast
Channel: stardot.org.uk
Viewing all articles
Browse latest Browse all 5780

programming • Instruction for a C function pointer call on 65816

$
0
0
I'm hoping the combined brains here could give me some help on 65816 coding ideas.

I've recently been playing the the vbcc 65816 target and have managed to get a hacked about version of the Xinu operating system working on the C20K / Blitter board with 65816. Xinu is a Unixey operating system used to teach OS theory and accompanied by a nicely written text book

There were a number of challenges to doing the port - mostly due to the C code mixing uint32 and int when the 65816 has a 16bit int. The other was that the vbcc compiler generates code that requires the DP (direct page) register of the 65816 to be known at link-time. I wanted each Xinu process to have its own stack and direct page so I wanted to break this compile time requirement and be able to change the direct page.

The main stumbling block to this is that for calls on C function pointers the code generator looks like this:

Code:

  emit(f,"\t%s\t%s%d\n",jsr,labprefix,++label);  yval=NOVAL;  add_cmplist(label,p->q1.reg,JMPIND);
Which generates something like this:

Code:

JSLpreNNN...rtlpreNNN:jmp[dpreg]
Where dpreg is a 24 bit register in direct page which contains the function pointer. The trouble here is that the jmp [] instruction actually uses ABSOLUTE addressing so needs a fixed direct page!

I have come up with this horrendous kludge

Code:

          //push return address          emit(f,"\tphk\n");                      emit(f,"\tper\t%s%d-1\n",labprefix,++label);          //push rti sequence          emit(f,"\tpei\t(%s+1)\n",mregnames[p->q1.reg]);          emit(f,"\tphp\n");          emit(f,"\tphp\n");          emit(f,"\tpha\n");          emit(f,"\tlda\t%s\n",mregnames[p->q1.reg]);          emit(f,"\tsta\t4,S\n");          emit(f,"\tpla\n");          emit(f,"\trti\n");             //DB: return address label                   emit(f,"%s%d:\n",labprefix,label);  yval=NOVAL;
Which generates something like this (notes added)

Code:

phk; push return address bankperpreNNN - 1; push return addres - 1peidpreg + 1; push bank and hi byte of function pointerphp; reserve spacephp; push flags (for RTI)pha; save A (16 bit)ldadpreg; get low / hi bytes of function pointersta4,S; store on stackpla; restore Arti; use RTI to call functionpreNNN:
My aim in using RTI was to avoid doing a decrement which would be needed to use RTL but I'm sure there must be a better way of doing this. I was trying to avoid using any non-stack storage locations but maybe I need to use a temporary direct page register - that might mean extra work elsewhere though to make it interrupt safe...

Any ideas on how to improve this - in Xinu the function pointers are called fairly regularly but are not really on any critical timing paths but I would really like to get this slick before suggesting it as an option in vbcc!

D

Statistics: Posted by dominicbeesley — Fri Sep 19, 2025 6:43 pm



Viewing all articles
Browse latest Browse all 5780

Trending Articles