Shop OBEX P1 Docs P2 Docs Learn Events
Stampworks 10 — Parallax Forums

Stampworks 10

basicstampedebasicstampede Posts: 214
edited 2008-09-04 17:09 in General Discussion
I've been working on Stampworks Experiment 10, and modifying it to learn SX/B on my Prof. Dev. Board.

I've created 4 versions:

1.· Stampworks10_4LED_works.SXB
This is·a SX/B·version of the Stampworks·using 4 LEDs (originally for INEX board).· It works.

2.· Stampworks10_5LED_works.SXB
Same as above except I added 5th LED for my Prof. Dev. Board.· It also works.

3.· Stampworks10_4LED_int_works.SXB
This is same as the 4 LED version above except I use interrupt.· It works.

4.· Stampworks10_5LED_int_compile_err.SXB
This is same as the 5 LED version above except I tried to use interrupt.· It does NOT compile.·

It says:

"Line 399.· Error 44.· Pass 2.· Address 261 is not within lower half of memory page"

Why won't this code compile?· What does above·message mean?

Comments

  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-09-04 06:06
    If you're using an interrupt there is no need to monitor an external signal for updating a clock -- let the interrupt do it. I've attached an updated version of a program I showed you earlier; this one uses an interrupt to update the clock and refresh the display. Note that the foreground program is actually empty!

    Again, you can continue to try to crowbar BS2 programs in the SX, but you'll be doing yourself a big favor learning how the SX wants things done and just going that direction to start with. But far be it from me to dissuade you from an self-induced misery.... tongue.gif

    To answer your question about the program that's giving you an error, you have two SERIOUS issues:

    1) You're calling the interrupt every 5 milliseconds but consuming 5 milliseconds in the interrupt -- no time for the foreground program.
    2) I warned you before about using high-level commands like PAUSE in your programs (other than wrapped in a subroutine). You have five PAUSE statements in the interrupt and every one of them explodes out to a big chunk of assembly code so this is making the actual code in the interrupt quite long, long enough to push the jump table for subroutines out of the lower half of the code page were it resides.

    Post Edited (JonnyMac) : 9/4/2008 6:28:22 AM GMT
  • YendorYendor Posts: 288
    edited 2008-09-04 11:53
    First of all, take heed to what Jon is saying...
    I've converted several BS2 programs to SXB (many of them Jon's), as a lot of subject matter and sample programs are in BS2, so I know where you're coming from.·· There are some differences, but once you get the SX and SX/B knack, you're on your way.·· I've actually have had lots of fun converting the programs.···In addition, the PIC code is almost identical to the SX, and you have that avenue to explore as well.· Maybe, I'm just a masochist! [noparse]:o[/noparse])
    You'll soon get it...
    When you get to that point again after optimizing, there is a workaround I've learned, thanks to Zoot and Peter Verkaik.·
    Zoot said...
    The ISR has to fit in the lower half of page 0 or it will not work (this is how the SX is). The workaround has always been to start your interrupt with a JMP (aka GOTO) if your ISR is longer. In my apps I usually put the ISR code itself at the end (last code page).
    Here's a way of how to implement it.
    INTERRUPT
    '___________________________________________________________________________________
    
       GOTO ISR_Start
    '__________________________________________________________________________
    ' Subroutines / Jump Table
    '__________________________________________________________________________
    
    
    ' sub/func declarations here
     
    
    PROGRAM Start 'as normal
    
    ISR_Start:   'new interrupt code location
    
    'long ISR code here
    
    
    RETURNINT 
    '___________________________________________________________________________________
    
    '__________________________________________________________________________
    ' Program Code
    '__________________________________________________________________________
    
    Start:
    
    

    ···· Rodney

    Post Edited (Yendor) : 9/4/2008 12:17:30 PM GMT
  • basicstampedebasicstampede Posts: 214
    edited 2008-09-04 13:38
    Jon, first thank you for all your help.· I am so glad to "meet" you in this forum.· I'm an avid fan of your N&V articles (I have every single one of them).·

    And I think Stampworks is such a great learning tool that I am trying to learn about SX/B by doing Stampworks experiments in SX/B.

    I received your suggestions and I will study it and try it.

    Meanwhile, I was just experimenting for the sake of experimenting, taking your suggestion from a previous N&V article [noparse]:)[/noparse]

    Thanks for the hint about not using PAUSE inside ISR and calling it too often.·
  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-09-04 15:53
    As Rodney points out, once you get the knack for SX/B things will really start to flow -- and it really is a lot of fun.

    On interrupts: you want to keep them as short as possible and don't do any "big" things (like delays) in them. Remember, the interrupt is disrupting your main program and you want to minimize this disruption. It does take a new way to look at things but, again, once you get the hang of it you'll have a blast.

    On my PAUSE comment: what I want to clarify is that you can have as many delays in a program as required (just not in the INTERRUPT section); what I strongly suggest, however, is that the PAUSE keyword appear only once in your listing and be wrapped up in a subroutine that you can call (I always call it DELAY_MS). What this does is put all the code for PAUSE in one place and only once; this saves your code space. If you look at the list file (use Ctrl-L in the IDE) for the program that was giving you trouble you can actually see all of those PAUSE statements compiled in place and taking up a lot of space in the listing.

    Finally, keep in mind that SX/B is a living, breathing entity (Bean is the wacky scientist in the lab coat) so programs that I wrote a couple years ago I would (and do) write differently today. SX/B has matured and, frankly, I've become a better programmer. I am constantly refining my programs as I learn new tricks from gurus like Bean, PJV, PJ Monty, Guenther Daubach, Peter Verkaik, and others -- you get the idea, there's a bunch of smart cats here so take advantage of their brains. I do!
  • basicstampedebasicstampede Posts: 214
    edited 2008-09-04 16:32
    JonnyMac, I read the SIMPLE_CLOCK_ISR.SXB. Wow, that is some clever coding!

    I do have 2 questions, arising from my lack of knowledge.

    1. What is the purpose of isrFlag = 1 statement?
    Does it reset a flag, to prevent repeat calls to ISR? Should it be set to 0? (would be more intuitive to me)

    2. I understand about your suggestion for creating DELAY_MS. But my understanding of assembly is poor.

    Can you please explain what these lines do?
    Is backslash part of SX assembly? (Forgive my igonrance here).

    SUB DELAY_MS
    duration VAR __WPARAM12 ' alias

    \ SB __PARAMCNT.1 ' skip if word passed
    \ CLR duration_MSB ' clear MSB if byte passed

    DO WHILE duration > 0
    \ CLRB isrFlag
    \ JNB isrFlag, $
    DEC duration
    LOOP
    ENDSUB
  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-09-04 17:09
    1. This is a trick I learned from PJV, one of the aforementioned gurus. Here's the deal: the interrupt runs at a known rate so we can use that rate for external timing. This is important because time-based functions like PAUSE get hosed up when we use interrupts. This is why -- as in this program -- when we're using an interrupt the code inside DELAY_MS changes; in this case it simply counts interrupt cycles which are marked by setting the isrFlag to 1. In your program the interrupt rate is conveniently set to 1 millisecond so DELAY_MS is very straightforward: it clears the flag, waits for another, and then decrements the delay (millisecond) counter until it reaches zero.

    In the end, setting isrFlag to 1 is way to tell the foreground the the ISR has run.

    2. There are two ways to insert Assembly statements into an SX/B program: the \ character allows for a single line, or we can put in a block of statements using ASM..ENDASM. For one or two lines I tend to use \, for more than that I usually have an ASM..ENDASM block.
Sign In or Register to comment.