Jump to content



1

JSR to RTI?


10 replies to this topic

#1 Propane13 ONLINE  

Propane13

    Stargunner

  • 1,385 posts
  • Location:Philly

Posted Fri Sep 7, 2007 12:45 PM

Hi all,

Let's ask a silly programming question as a warm-up exercise.
Let's say I have an interrupt routine already made, and it completes with an RTI.

Then, let's say that somewhere else in the code, I want to use that same interrupt code.
What happens if I JSR to it, and use the RTI to get back (instead of an RTS)?
Anything serious? I would assume that the 3-bytes are still pulled from the stack (status flags, plus return address), so would there be anything different with using an RTI over an RTS?

Thanks!
-John

#2 Flipper OFFLINE  

Flipper

    Star Raider

  • 54 posts

Posted Fri Sep 7, 2007 1:58 PM

View PostPropane13, on Fri Sep 7, 2007 1:45 PM, said:

Hi all,

Let's ask a silly programming question as a warm-up exercise.
Let's say I have an interrupt routine already made, and it completes with an RTI.

Then, let's say that somewhere else in the code, I want to use that same interrupt code.
What happens if I JSR to it, and use the RTI to get back (instead of an RTS)?
Anything serious? I would assume that the 3-bytes are still pulled from the stack (status flags, plus return address), so would there be anything different with using an RTI over an RTS?

Thanks!
-John

Sadly, it doesn't work. From a 6502 information site "Note that unlike RTS, RTI does NOT add one to the destination before placing it in the Program Counter (PC)". Thus, you'll end up returning to the wrong address. Also, RTS does NOT pull the processor flags, so you're stuck there too.

One method which may be available to you is to use BRK, NOP. BRK is really a software interrupt, thus can be returned from via RTI. Note, when used as a software interrupt and you want to get control back to the main program, you must follow the BRK with a NOP. The pointer stored by BRK is off by one, and will skip the next byte of program code. Of course, since the BRK pointer is stored in ROM and shared with the IRQ pointer, this may get you no savings.

#3 Thomas Jentzsch OFFLINE  

Thomas Jentzsch

    Thrust, Jammed, SWOOPS!

  • 16,744 posts
  • Always left from right here!
  • Location:Düsseldorf, Germany

Posted Fri Sep 7, 2007 2:16 PM

Well, it does work, but you have to adjust the return and stack pointer.

#4 Flipper OFFLINE  

Flipper

    Star Raider

  • 54 posts

Posted Fri Sep 7, 2007 6:19 PM

View PostThomas Jentzsch, on Fri Sep 7, 2007 3:16 PM, said:

Well, it does work, but you have to adjust the return and stack pointer.

Ok..true...you could have two entry points. One with some setup code to get the stack right, and then one for the interrupt routine.
It's a little bit ow either way.

#5 supercat OFFLINE  

supercat

    Quadrunner

  • 6,367 posts

Posted Fri Sep 7, 2007 7:36 PM

View PostThomas Jentzsch, on Fri Sep 7, 2007 3:16 PM, said:

Well, it does work, but you have to adjust the return and stack pointer.

An alternative would be to have a JSR-style entry point at $FAxx which performed a PHP and then jumped to the interrupt routine. If $FAxx is not convenient, $F0xx could be used provided the JSR instruction was followed by a BRK (which would not be executed).

Edited by supercat, Fri Sep 7, 2007 7:37 PM.


#6 Nukey Shay OFFLINE  

Nukey Shay

    Sheik Yerbouti

  • 20,458 posts
  • Location:The land of Gorch

Posted Fri Sep 7, 2007 8:14 PM

What is the point? Are you trying to save a cycle by avoiding the use of BRK in one instance? If so, the inclusion of a seperate entry point to adjust the stack won't work.

How long is the interrupt? If it's not very long, it might be better just to avoid using a JSR subroutine to begin with...and code that portion directly into the main program (also saving the cycles needed to jump there and back).

Edited by Nukey Shay, Fri Sep 7, 2007 8:16 PM.


#7 Rybags OFFLINE  

Rybags

    Quadrunner

  • 10,312 posts
  • Location:Australia

Posted Fri Sep 7, 2007 8:41 PM

One way you could do it - test the "I" flag.

A NMI or IRQ routine will always be called with IRQs masked.

So, you'd need:
IRQSTART PHA
;
; ... rest of IRQ routine here ...
;
PHP
PLA
AND #4
BNE IRQMASKED
PLA
RTS
IRQMASKED PLA
RTI

Of course, that assumes that you're not doing SEI in your main loop before calling the routine.

#8 batari OFFLINE  

batari

    )66]U('=I;B$*

  • 6,236 posts
  • begin 644 contest

Posted Fri Sep 7, 2007 9:10 PM

There are several code solutions, depending on your needs.

If you don't care about X and flags upon entry, you know SP != 0 or 1 and PCL of the return address <> $FF, it's really easy. (The return address can be checked at assembly, so that shouldn't be an issue.)

JSRroutine
  PHP
  TSX
  INC $102,x
IRQroutine
  .... 
  RTI

SP != 0 or 1 might only be known at runtime, so if that's the case, this will work:

JSRroutine
  PHP
  TSX
  INX
  INX
  INC $100,x
IRQroutine
  .... 
  RTI

Furthermore, if you care about X and flags, that can be worked around as well.

#9 Propane13 ONLINE  

Propane13

    Stargunner

  • 1,385 posts
  • Location:Philly

Posted Tue Sep 11, 2007 11:36 AM

Hello,

The point isn't really efficiency.
I've got a... hardware project where something works in one environment but not another.
So, I wanted to see if I could short-circuit a call to a pre-existing ISR routine on powerup, and what it would do, as a test.

-John

#10 doppel OFFLINE  

doppel

    Star Raider

  • 65 posts

Posted Fri Nov 27, 2009 4:50 AM

It seems to me that fixing the return address after a BRK would be less efficient than adding a NOP after each BRK. Unless there are lots of BRK opcodes in your code.

#11 Thomas Jentzsch OFFLINE  

Thomas Jentzsch

    Thrust, Jammed, SWOOPS!

  • 16,744 posts
  • Always left from right here!
  • Location:Düsseldorf, Germany

Posted Fri Nov 27, 2009 12:27 PM

View Postdoppel, on Fri Nov 27, 2009 4:50 AM, said:

It seems to me that fixing the return address after a BRK would be less efficient than adding a NOP after each BRK. Unless there are lots of BRK opcodes in your code.
Depends. If you know the stack pointer, you just need 3 byte to correct the return address.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users