6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Mar 29, 2024 8:10 am

All times are UTC




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Callback Tables
PostPosted: Sun Jul 21, 2019 4:34 pm 
Offline

Joined: Sun Jul 21, 2019 4:21 pm
Posts: 6
I've setup some tables with callbacks and parameters indexed by x. Unfortunately I didn't realize an instruction didn't exist when I wrote it so now I'm having trouble thinking of a workaround (and scrapping and starting over doesn't seem like a plan as I can't see any way else to do it with variable size parameters).

The offending instruction:

Code:
JML (JumpTable, X)


Which is part of a "JSL (JumpTable, X)"
Code:
PHK                     ; Push RTL address
PEA .callback_return-1
JML (JumpTable, X)
;some code
.callback_return:


The biggest problem, I think, is my JumpTable is in RAM... but maybe that's not an issue? Also, I'm not in Bank 0 afaik, but if that's an issue I can definitely try to shove some code around.
Any help with this? I'm stumped. Thanks in advance!


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Sun Jul 21, 2019 10:44 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3328
Location: Ontario, Canada
Welcome!

This is hurriedly written and untested, but maybe it'll give some ideas. I hope you can tolerate the fact the A register gets bombed. And I'm assuming your jump table doesn't straddle a bank boundary. :)

As you can see, my suggested code copies the three-byte destination address to stack, then does an RTL. But it's awkward pushing an odd number of bytes to stack when the 816's Acc/Memory are in 16-bit mode. So, I use PHA to push 2 bytes then use STA to write 2 more bytes... after only having made room on stack for one. If I this works as intended then the mid byte will get copied to the same place twice, but that's harmless.

About equally good would be to push 16 bits then set Acc/Memory to 8-bit mode and push 8 bits; then set Acc/Memory back to 16-bit mode. I think coding it my way saves 2 bytes, although it's not any faster.

Code:
PHK                             ;Push the final RTL address
PEA .callback_return-1
                                ;Next, push (the 24-bit destination address)-1.
                                ;Destroys A. A must be in 16-bit mode.
                                ;Note: -1 is already pre-added to each entry in the table

LDA JumpTable+1, X              ;get the mid and high bytes of the 24-bit address
PHA                             ;push the two bytes
LDA JumpTable, X                ;get the low and mid bytes of the 24-bit address
PHK                             ;decrement S to make room for 1 more byte on stack
STA 1,S                         ;write the low byte and re-write the mid byte
RTL                             ;"Return" instruction used as a Jump
;some code
.callback_return:
(edits)

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Last edited by Dr Jefyll on Mon Jul 22, 2019 3:11 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Mon Jul 22, 2019 2:37 am 
Offline

Joined: Sun Jul 21, 2019 4:21 pm
Posts: 6
I'm digesting this, haven't used PEA yet and my callbacks are 16-bit I think, although I may have done that part wrong... Thank you so much for helping me out! I'll ping back if I have further problems. Thanks again!

Edit: *understood PEA yet*, I was tired when I wrote this. Clearly I used it. Those 3 lines are actually from somewhere on this site...


Last edited by Runic_Rain on Mon Jul 22, 2019 10:24 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Mon Jul 22, 2019 3:28 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3328
Location: Ontario, Canada
Runic_Rain wrote:
I'm digesting this, haven't used PEA yet and my callbacks are 16-bit I think, although I may have done that part wrong...
Hmm, it's also possible I've misunderstood your overall intent. But focusing just on the JML (JumpTable, X) instruction you wanted, here are some suggested replacements. They require that each entry in the table will point to (desired destination)-1.

This version destroys A ...
Code:
LDA JumpTable+1, X           ;get the mid and high bytes of the 24-bit address.
PHA                          ;push the mid and high bytes to stack
LDA JumpTable, X             ;get the low byte and re-get the mid byte
PHK                          ;this push is only to subtract 1 from S
STA 1,S                      ;write the low byte and re-write the mid byte
RTL                          ;"Return" instruction used as a Jump
... but to preserve A you can precede the above with a PHA and require that each of the code sequences jumped to via the table must do its own PLA.

This way preserves A somewhat more slowly, but omits the need for a PLA at every jump target.
Code:
PHK                          ;this push is only to subtract 1 from S
PHA                          ;this push is only to subtract 2 from S
PHA                          ;this push is for actually saving A
LDA JumpTable+1, X           ;get the mid and high bytes of the 24-bit address
STA 4,S                      ;write the mid and high bytes to stack
LDA JumpTable, X             ;get the low byte and re-get the mid byte
STA 3,S                      ;write the low byte and re-write the mid byte
PLA                          ;restore A
RTL                          ;"Return" instruction used as a Jump

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Mon Jul 22, 2019 10:34 pm 
Offline

Joined: Mon Sep 14, 2015 8:50 pm
Posts: 110
Location: Virginia USA
If you have room in the bank of tables why not write:

JMPTABLE:
jmp (jmptable,x)

ldx #something
jsl JMPTABLE

and end each JMPTABLE code with an rtl?

cheers,
Andy


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Tue Jul 23, 2019 3:52 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1918
Location: Sacramento, CA, USA
Yes! The "springboard" technique can potentially be very useful and economical in these types of situations.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Tue Jul 23, 2019 6:39 am 
Offline

Joined: Sun Jul 21, 2019 4:21 pm
Posts: 6
I already covered that with handyandy via PM. It's a callback. Therefore the jump table is in RAM (x-indexed in this case because it's multi-callback) if it was in ROM it wouldn't actually be a callback. Loading code after every RAM slot is doable I guess... still... The other issue of course is said jumps in table are long. Still contemplating what Dr. Jefyll said and trying to make it work, think I might have something? If not, I'll post the code. Was trying to avoid that as it's long, not the most elegant, and makes the question read more like: "Do it for me!" :P

(All this assuming I'm understanding the intended springboard correctly of course.)


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Tue Jul 23, 2019 6:55 am 
Offline

Joined: Sun Jul 21, 2019 4:21 pm
Posts: 6
In pseudo-C for ?clarity?:
Code:
typedef unsigned_24bit_address func_ptr
func_ptr jumptable[SOMESIZE]

8bit addcallback(func_ptr)
   {
   x = next_unused();
   jumptable[x] = func_ptr;
   return x;
   }

void main()
   {
   while(x)
   {
      if(doCallback)
         {
         *fucnc_ptr[x](); // call stored address (JSL jumptable, x) <---offending
         }
      x--
      }
   }

I said my 24bit address *was* 16bit though. (Which I didn't realize was wrong, need to store and restore the bank's 8 bits)


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Tue Jul 23, 2019 2:23 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
The springboard doesn't need to be anywhere near the jump table itself. In particular it exists in Program space while the table is accessed through Absolute data space, so may be in different banks of memory.


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Tue Jul 23, 2019 3:06 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
JMP (abs) and JMP (abs,x) always interpret the address as being in the same program bank as the JMP itself. JMP [$abs] always interprets its address as being in bank 0.

If your vector table is in bank 0 and you have code space to spare then you could JMP (abs,x) thru a table of addresses to a JMP [vec] for an appropricate slot in your table.
Code:
  .page0

vec0 .space 3
vec1 .space 3
vec2 .space 3

  .code

; X = vector number * 2

CallVector:
  jmp ($+3,x)
  .word call0
  .word call1
  .word call2

call0: jmp [vec0]
call1: jmp [vec1]
call2: jmp [vec2]

If your vectors are not in bank0 then pushing the address to the stack and performing an RTI (or address - 1 and RTS) might be easiest solution.

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Tue Jul 23, 2019 3:24 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1918
Location: Sacramento, CA, USA
I could be repeating the ideas of others in a slightly different manner, but here's how I see it. Looking at your pseudo-C, it seems that your jumptable[] is an array of 24-bit addresses. How hard would it be to make it an array of 32-bit JML al instructions instead, with a JMP (jumptable,x) hanging out nearby in the same bank with the array? If I'm not mistaken, you can then simply JSL al to your JMP (jumptable,x) from anywhere, and the double springboard does the rest for you (at the expense of an extra byte for each array element, a 3-byte JMP and a handful of machine cycles).

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Tue Jul 23, 2019 8:43 pm 
Offline

Joined: Sun Jul 21, 2019 4:21 pm
Posts: 6
Thanks all. I think I might have an idea on how to do this now. Will report back with whatever comes of it! My references might not be the best though.
Afaik you could say JSL is roughly equivalent to PHK : JSR meanwhile RTL roughly is "PLK" : RTS, correct?
If so, what is RTI roughly? (ie, how does it effect the registers/stack? I've been using https://wiki.superfamicom.org/65816-reference, which is probably not the best thing out there...)


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Tue Jul 23, 2019 9:02 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
Download a copy of the programming manual
http://archive.6502.org/datasheets/wdc_65816_programming_manual.pdf
Or buy a paper copy
https://www.amazon.co.uk/Programming-65816-Including-65C02-65802/dp/0893037893/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=1563915710&sr=8-1

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Tue Jul 23, 2019 9:35 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1918
Location: Sacramento, CA, USA
Runic_Rain wrote:
Afaik you could say JSL is roughly equivalent to PHK : JSR meanwhile RTL roughly is "PLK" : RTS, correct?

Err ... no. I don't believe either of those statements to be correct in general practice, unless you're strictly limiting yourself to a single bank, in which case they are superfluous (and the stack order must be wrong for one of of your examples too).

Quote:
If so, what is RTI roughly? (ie, how does it effect the registers/stack? I've been using https://wiki.superfamicom.org/65816-reference, which is probably not the best thing out there...)

RTI is almost like PLP : RTS but there's an annoying "off-by-one" for the return address.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
 Post subject: Re: Callback Tables
PostPosted: Wed Jul 24, 2019 1:58 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
In native mode, RTI is more nearly equivalent to PLP : RTL - but again with that one-byte offset. The difference is simply that the PBR is reloaded as well as the status register and the PC, with a total of 4 bytes being pulled off the stack.

There's also the detail that these are atomic operations; separate PLP : PLK : RTS instructions would usually re-enable interrupts (and thus permit entering a nested interrupt handler) before either of the latter two were executed, and the PLK would potentially move the program counter off the RTS so that it never gets executed. That's probably why there is no PLK instruction.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: