Retp vs retw
SamMishal
Posts: 468
Hi all,
Can any one who knows please clarify some thing for me?
According to the manual RETW #Constant is just like RET but loads the W register with the Constant.
Ie RETW is incapable of returning accross pages like RETP.
Is this true? Or is RETW like RETP?
Thanks
Samuel
·
Can any one who knows please clarify some thing for me?
According to the manual RETW #Constant is just like RET but loads the W register with the Constant.
Ie RETW is incapable of returning accross pages like RETP.
Is this true? Or is RETW like RETP?
Thanks
Samuel
·
Comments
All of the returns from a call, RET, RETP, and RETW will return to the instruction following immediately after the call.
Surely you can test this or try it with Guenther's simulator yourself? No?
Cheers,
Peter (pjv)
hiere is a little test program:
First single-step it with SXSim, or with SX-Key on a "real chip" as is. Sub1 is called from Main with Sub1 located in the same page as Main. In Sub1, a jump to _Sub1 is performed which is located in Page $200. Therefore, it is necessary to set the page correctly before the jump. _Sub1 terminates with RETP which means that the page is restored to the page of the calling code (Main, or page 0 in this case), and the next instruction following the call (clr 8) will be executed next.
Now remove the semicolon in front of MISSING_PAGE, and single-step again. When the jmp _Sub1 instruction is executed, you will notice that the jump does not go there but to Main instead. This is because the page is wrong (still page 0), so the jump is performed to address 0 in page 0 (which is Main) but not to page $200, address 0, where _Sub1 is located.
Next, place a semicolon in front of MISSING_PAGE again to correct that error, and remove the semicolon in front of BAD_RET.
Again single-step the program. On the first glance, it seems as if everything is fine but notice what happens when the jmp Main is executed after the subroutine call, and the clr 8. The program jumps to _Sub1 and not to Main as expected. As this time, the subroutine ends with RET insted with RETP, the return from the subroutine is performed as expected, but the selected page is still $200. This means that jmp Main jumps to address 0 in page $200 (to _Sub1) instead to address 0 in page 0 (to Main).
So both return instructions cause a return to the instruction following the call but RETP in addition restores the page bits in STATUS to the caller's page. To be honest, I could not find a situation where using RETP caused trouble, even when the call and the return are both located in the same page. So I alays use RETP instead of RET just to avoid such problems.
Instead of RETP you might use the sequece:
page 0
ret
in the subroutine which restores the page back to Main before returning but this is no good programming style, as a subroutine should be designed like "black boxes", not knowing who called them and from where. Instead, you might place the
page 0
instruction following the call Sub1 instruction in Main. But why make things more complicated than necessary - simply use RETP, and you are in good shape.
RETW also does a return from a subroutine. In addition, it stores the parameter given to RETW in W on return. Note that RETW does not rsetore the page, so be careful when changing pages in between.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
Thank you for all the explanation. I actually know the difference between RET and RETP.
What I was confused about is whether RETW behaves like RET or like RETP after
setting the W register.
I have done some testing and discovered that it is like RET in that it does not restore
the Page (top three bits of the Status register). IE it pops the 9 bit PC register of the stack
without restoring the page 3 bits inside the Status register.
So RETW <constant> is limited to being on the same page as the calling line
unless there is an express PAGE command just before the RETW command.
Anwy I think IREAD is much better and I will use this instead.
Regards
Samuel
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
yes, you are right (and I mentioned this in my last post), RETW does _not_ restore the page bits.
Paul's suggestion replacing the RETW by mov w, #const + retp is one option but it no longer allows you to use SASM's nice feature to follow RETWs with many parameters to create kind of a table.
It is important to know that all RET instructions correctly restore the SX program counter (the internal 11 or 12 bit register) and the 8-bit PC register, so all RET instructions send program execution back to the right place. The pitfall is that RETP is the only instruction that also restores the page bits on return, where the others don't. Thus, later jumps or calls may go to "nowhere land", or to some un-expected location when the page was changed before to correctly address the subroutine.
Therefore, as I had mentioned before in my last post, another alternative is to have the calling code take care if setting the page bits correctly, like in
org 0
Main
page Sub1
call Sub1
page Main
.
.
org $200
Sub1
; Foo Foo
retw 1
IREAD is another interesting alternaitive to handle tables with constants but it is a bit more tricky, and requires a bit more code to handle it.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
THANK YOU VERY MUCH!!!!!!!!!
Your above post has answered my Puzzle as I was posting it. (see seperate post I have just finished doing)
Now the puzzle is clear.
RET and RETP and RETW would always return to the correct line in the correct page due to this restoring of the
actual 12 bit address. But only RETP restores the STATUS register and thus any subsequent jmps
would fail if RET or RETW are used from a long call (call @).
So one way around this is to use the RETW but in the next line after the call to use a PAGE to restore the
STATUS bits to the correct page..............I now can still use RETW but with this added precaution within
the calling code.........Thanks
BUT PLEASE READ the seperate thread I have just posted. I ahve an additional question there.
The question is :
If the PC register is a 9 bit register, then why do you only show 8 bits on the SXSim screen, and
by the way also the IDE DEbug does the same thing?
This can be confusing during the following of the code say when you are on a line $302 for example
The top 3 bits of Status would show %001 and PC $02 but·there is no indication that the actual address
is currently %0011 0000 0010 since the 4ths bit from the top is no where to be seen???????????
Regards
Samuel
Post Edited (SamMishal) : 1/14/2006 5:30:00 PM GMT
please don't think I'm picky - I just want to make sure that others who read this thread are not mis-led. The RETP instruction does _NOT_ restore the STATUS register - just the upper three PA bits in this register. All other bits, like Z, C, DC, etc. remain unchanged.
As I had mentioned in my last post, there is an internal program counter in the SXes (11 bit wide in devices up to the SX28, 12 bit wide in the SX 48/52 devices). This program counter is used to internally address program memory. The PC register that is mapped into the variable address space at address 2, and that can be accessed by program instructions is only 8 bits wide, and it represents the lower eight bits of the internal program counter. So SXSim exactly shows the eight bits that can be accessed (as does the SX-Key debugger).
The SX addressing scheme seems to be a bit weired on the first glance. To understand it, you always must keep in mind that each instruction the SX "knows" is always one word (12 bits) wide. Each instruction is composed of some higher bits that specify the instruction per-se, followed by some lower parameter bits that specify a value, like a constant or an address.
For example, the instruction code for JMP is composed like this:
101a aaaa aaaa
i.e. the leading "101" "tells" the SX to perform a jump, and the following 9 bits contain the target address. Obviously, 9 bits can only address 512 memory locations. To address all program memory, 11 bits (or 12 for the SX 48/52) are required. Therefore, to compose a complete jump address, two (or three) of the page bits in the STATUS register are used. The resulting full address is then copied into the internal progral counter to actually perform the jump.
Similar to JMP, the code for CALL is:
1001 aaaa aaaa
Here, the instruction part is 4 bits wide, only leaving 8 bits for the call address. To compose a full call address, the 9th bit is always set to 0 here, and the upper two or three bits are read from the upper STATUS register bits, as before. This is the reason why entry points of subroutines can only be located within the first half of each code page as there is no room in the instruction code for the 9th bit, so it is always cleared.
BTW - if you have my book on hand, you'll find a more detailled explanation at page 157 ff. You can also find similar information in the SX datasheets.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
Thank you again.
Please look at the other thread for one more issue.
I would really like to see the real Programme Counter on the SXSim (and IDE DEbug) .
I think in some cases it would make things a lot clearer (as we have seen in the case of RET/P/W).
I think that just seeing the PC($02) and STATUS($03) is not enough and even misleading in some cases.
I wish the designers of the SX gave us a break. This whole Subroutines being confined to the upper 256 12bit words
of memory is annoying and can lead to funny errors.
I understand from the above description of the MicroCode that they are limited but could they not just
as esily have designed the memory to be 13bits instead of 12 (additional 4K bits not too expensive).
This way the MicroCode 4bits would not interfere with the 9th bit of the Call address.
Anyway even the mighty 80286 had paging issues. That is why my favourite Micros are the
Motorolla ones where memory is just one big array.
I like the Harvard architucture and how it facilitates one clock instructions, but that is only really a trick
since most instructions are not really one clock but due to the pipe line they appear to be so. And even then
there are many instructions that even with the pipe line trick still require multi cycles, and many instructions
are compound instructions.
The RISC and enhanced Von Neuman Micros with pipelines and multi pipelines can achieve one clock
instructions and have many more REAL one clock instructions.
I use the 68HC12 and find it a lot easier to develop for.
But I love the price/size/speed/ and functionality of the SX. That is why I will stick with it.
And Thanks to people like you (and Parallax) providing the tools and Knowhow,
it can be quite a viable Micro.
Thanks again
P.S. Please look at the other thread for a wish list for your next upgrade to your ABSOLUTELY
INDESPENSABLE SXSim.
Samuel
you made an interesting suggestion - it would be pretty easy for SXSim to display the status of the internal program counter - in case I find some more free space in the main window . The IDE Debugger definitely can't do it as the SX device does not allow reading it.
I can't share with you your complaints about the SX design. When the SX was created, the major goal was to design a controller being compatible by some extend to other products already available, plus some enhanced and important new features, like high speed execution with preciely timed, deterministic interrupts, allowing to implement customized peripherals just in software. The SX is not the first controller making use of program memory paging, and variable memory banking. Once you've got the idea, it is pretty easy living with it.
Sorry, I also must disagree with you concerning compound instructions - the SX instruction set does _not_ contain any compound instructions at all. The developers of the assembler have added them for user-convenience. You may think of them as pre-defined macros. Sometimes, compound instructions can cause a lot of problems when placed at the wrong place, e.g. following a skip or conditional skip instruction. It is simply up to you using compound instructions or not - all possible programming tasks can be achieved without using compound instructions at all.
There is no question - other types of controllers/processors but the SX may be better suited for certain applications - you always have the freedom to decide which device you might use but when you decide to go with the SX, you will have to live with its structure and how it must be handled. As you certainly know, the SX is a "frozen" design, so don't expect new enhanced versions with more/other features.
From my point of view, I can only say that I make most of my current income from designing various applications around the SX (from protocol converters up to heavy-duty motor controllers), and I like the SX so much because I can customize it the way I specificly need it, simply in software, without the need seaching the feature lists of other controllers, and then figuring out how to deal with a specific variant of another controller family.
So, we should not complain about what the SX can't do, or might be doing better - let's take and use it as it is, and - most important - we should be glad to know that the SXes are now in the "right hands". Since Parallax has taken over the SX product line, I feel much more comfortable that it will remain viable for a long period of time. A small company like the one I'm running can't spend the time & money to re-designing all its products just because a major part like the SX would no longer be available. This is one of the reasons why I hold the SX-flag high.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
I am new to the SX and already like it a lot. I was just griping about somethings, but the advantages
outway the small number of disadvantages.
Thus in my book too, the SX is a winner.
And as you say thanks to Parallax, but also thanks to you for the SXSim, and thanks to all the people who write
such good books as yours and Al Williams'.
Regards
Samuel