Shop OBEX P1 Docs P2 Docs Learn Events
A question about temporarily disabling interrupts — Parallax Forums

A question about temporarily disabling interrupts

Paul BakerPaul Baker Posts: 6,351
edited 2004-12-13 03:39 in General Discussion
I am mulling over the possibility of using the newly disclosed "secret" instructions to implement a call instruction (via macros) that does not have the limitation of requiring the target address to be in the lower half of a page. I would like it to be "bullet proof" (ie not foul up when using the SX-Key in debug mode and an interrupt occurs).

Since I have no way of altering the SX-Key's method of running in debug mode, the only other option is to disable the interrupts temporarily. But not knowing the details of exactly how·disabling interrupts occurs leaves me with this question: If I were to disable interrupts, would the mechanism that sets the WKPND_B register and·RTCCOV bit still operate while interrupts are disabled so that when they are re-enabled the interrupt occurs? (the watchdog timer interrupt is incompatible with debugging, so I don't care about that interrupt source)

I understand the possibility of missing multiple interrupts, but I only intent on disabling the interrupts for a few cycles (when using the secret instructions).

I haven't figured out how to encompass the reti in the protected section yet, but thats another issue (it will likely require a "def _DEBUG_MODE_" option set that inserts a re-enabling interrupts section at the head of any routine called by this method).

If I can accomplish this and have a macro call instruction (similar to the _bank macro), I think we can finally do away with the space wasting jump tables necessary with large programs which have many subroutines (my current project has 131 possible jump table entries which I consider a waste of program space and clock cycles).

Paul



Post Edited (Paul Baker) : 12/12/2004 4:42:31 PM GMT

Comments

  • James NewtonJames Newton Posts: 329
    edited 2004-12-12 19:56
    Paul, I may be wrong on this, but I think it will be more effective to use the macros I set out at:
    http://www.sxlist.com/techref/ubicom/sasmtemp.src·and
    http://www.sxlist.com/techref/ubicom/sasmmem.src
    to solve the "call subroutine in upper half page space" problem. The number of cycles required to load the target address and then reti to it are bound to be more than the call to an address set aside in lower half page space which then jumps to the actual subroutine in upper half page space.

    Subroutine MACRO
    ;Usage: Define a Global lable,
    ; Execute Subroutine macro,
    ; Assign :Entry to the value now set in SubEntryAddr.
    ; Continue the definition of the subroutine.
    ; Elsewhere, call @Sub:Entry where Sub is the global lable
    ; you defined for the subroutine.

    ;Example

    SUB1 Subroutine
    :Entry = SubEntryAddr
    ;continue with your subroutines code and return as normal


    ;elsewhere:
    Call SUB1:Entry


    The context switching idea for multitasking is more interesting (I think) and it would still benifit from the answer to your question.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ---
    James Newton, Host of SXList.com
    james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
    SX FAQ / Code / Tutorials / Documentation:
    http://www.sxlist.com Pick faster!



  • Paul BakerPaul Baker Posts: 6,351
    edited 2004-12-12 21:22
    James,
    I undertstand this technique, Im using it presently. However your comments have caused me to take stock with my perceived need with my current project and I·have concluded that _call would be of little benefit in my current implementation (Token based interpreter). However when I create the indirect threaded version of the same interpeter, I still maintain that this proposed method will reduce the complexity of the meta-compiler quite substantially since it will not have to track exactly where subroutines·are placed and precisely how to place them, it will only need to preferentially place the most used subroutines at the lower addresses.

    Additionally I think that any program which has a very large number of subroutines who's use is highly assymetrical would benefit from this alternate method of call. By reserving the lower half of each page to the subroutines most called and ones that are infrequently called are done using this alternate method, the system throughput should be increased overall since you are shoving all the overhead cost to only those subroutines which are called infrequently.

    Paul

    I agree that this technique may be of more use to other applications which would benefit from use of the secret instructions, I am simply being somewhat myopic since I do not presently have an application which requires the need to develop·a RT-MTOS.

    Also this technique would greatly simplify the creation of DTC (direct threaded coding) and especially STC (subroutine threaded coding), though I have no current plans for doing either.

    Post Edited (Paul Baker) : 12/12/2004 10:26:37 PM GMT
  • pjvpjv Posts: 1,903
    edited 2004-12-12 23:44
    Hello Paul;

    Yes, you can do what you're attempting, but you will have to manually save the address where you want to return to prior to jumping to the "called" suroutine.

    As James said however, there is some overhead associated with this approach, and there are·simpler ways to achieve your end.·That understood though, here is an approach, part of·what I do in my RTOS.

    A code snippet:


    pushPC········· macro················································ ;
    ······················· dw······ $04B······································ ;
    ······················· endm················································· ;
    ·

    ······················· instruction
    ··········· ··········· instruction
    sav_return····· mov···· ret_addr_hi,#(S+3)>>8······· ; save hi return address 4bits
    ··········· ··········· mov···· ret_addr_lo,#$+3················· ; save lo return address 8bits
    ··········· ··········· jmp····· subroutine····························· ; pseudo call
    return_here··· instruction······ ··································· ; continue
    ······················· instruction·········································· ;··········
    ·
    ·
    subroutine····· instruction·········································· ;
    ······················· instruction·········································· ;
    ······················· instruction·········································· ;
    ······················· mov···· m,ret_addr_hi······················· ;
    ······················· mov···· w,ret_addr_lo······················· ;
    ······················· pushPC············································· ; dw $04B, prep return address into PC shadow
    ······················· reti······ ··············································· ; return to “return_here” in mainline


    Do realize however that on returning via the RETI instruction, the shadow stacks are all popped, and the·previous values of W, STATUS and·FSR are overwritten by the values in the stacks. Probably that's OK, otherwise you will need to save these in the "subroutine".

    Clearly, all this can become rather complicated if complicated if the routine needs to be re-entrant.

    Hopes this helps.

    Peter
  • Paul BakerPaul Baker Posts: 6,351
    edited 2004-12-13 01:49
    Thanks for the help Peter, yeah I plan to mimic the behavior of call by just doing the shadow pushing of all the registers that are affected by reti, and I knew I had to create my own call stack, I'll probably implement a "fast" version using some memory and some stack routines, and a slow version using the FIFO command. I have already coded up the core of the indirect threaded engine using documented commands by using a couple registers to load the address stored in program memory and calling a wrapper subroutine which takes the address and executes a jump to that address, the jumped to routine returns control by executing the ret instruction (the wrapper routine does not have a ret instruction).

    A quick primer for those of you who don't know what I'm talking about, indirect threaded code is a series of addresses which indicate program flow, each address is fetched from program memory and a subroutine call to that address is executed, after it is done executing it returns control to the executive program (interpreter engine) which gets the next address and starts the process over again, it is one of four methods of implementing an interpreter: Token (TTC) which is what the basic stamp does, Indirect (ITC), Direct (DTC), and Subroutine (STC). On the SX TTC and ITC (via the wrapper subroutine) is pretty straight forward, but because of the limitation of the call function special care must be used when trying to implement DTC or STC since absolutely no addresses in the upper-half of the page can be done. This complicates the design of the engine and the meta-compiler (a program which translates code written in one language into another language (typically assembler for the target system)) SX-B is an example of a meta-compiler since it translates Basic instructions into SX assembly instructions.

    Paul

    I got the inspiration for implementing ITC on the SX one day by noting that program words are 12 bits which represents 4K unique values, exactly the·same size as in the SX52 code space! Coicidence? I don't know, but it begs for exploitation. BTW ITC is typically quite a bit faster than TTC (my codeups prove this is the case for the SX).·Those of you with enough experience with this sort of stuff can probably deduce which language Im trying to implement on the SX·smilewinkgrin.gif

    PS Im about to go incommunicato again (still using company computer, but on the weekend Im here on my own dime and these piddly little posts dont clog bandwidth since noone else is here) Personal message me If you need to contact me and I will converse with you via email (thats accepted use,·why? I dunno, go figure)

    Post Edited (Paul Baker) : 12/13/2004 2:21:16 AM GMT
  • Paul BakerPaul Baker Posts: 6,351
    edited 2004-12-13 02:39
    Oh I just noticed, Peter do you know the answer to my original question about disabling interrupts temporarily and not missing events during the disablement? I noticed it wasn't explictly refered to.

    Gnight all,
    Paul

    (has to be back in @ 5am, God how I hate end-of-quarters)
  • pjvpjv Posts: 1,903
    edited 2004-12-13 03:39
    Hello Paul;

    I'm not 100% positive because I have not specifically tested it, but I believe that the wake-up pending register and the RTCC overflow registers will operate properly, and generate an interrupt·the instant·it is re-enabled. Do realize however, that only the SX48/52 have an RTCC overflow bit. Also they have an M shadow register, I believe only one level deep.

    Peter
Sign In or Register to comment.