Shop OBEX P1 Docs P2 Docs Learn Events
CALL and C/Z flags — Parallax Forums

CALL and C/Z flags

To code an IF..THEN..ELSE in pasm as short as possible I had the idea of something like this:
		testb	flags,#2 wc
	if_c	call	#ThenFunc
	if_nc	call	#ElseFunc
For this to work correctly I have to make sure that the C flag is preserved until after the first call. The P2 instructions docs say that CALL pushes the C/Z flags onto the stack. But how are they restored? Do I have to add a wcz postfix to the RET instruction? If yes then I can't use the _ret_ prefix, right? A wcz after the CALL is wrong, I think. It would set C=D[31] and Z=D[30] according to the docs.

Comments

  • evanhevanh Posts: 15,192
    Spot on, all points correct. I had advocated for _RET_ to always restore the flags but others didn't want it.

  • Cluso99Cluso99 Posts: 18,069
    There are cases where you specifically do not want to restore the cz flags - where the subroutine passes the results back using c/z flags. This was the only case possible on P1 so that is why _RET_ does not restore the flags. If you want the new behaviour then you need to use RET wc/wz/wcz.
    _RET_ does not have any spare bits left to enable/disable restoring the flags.

    In the ROM SD driver and the serial/debugger I have the need for both cases. In the SD Driver I pass back the flags from the bottom level routine right back up to the top. I have carefully crafted the code to do this. In the serial/monitor, since it is a bunch of callable routines form user code, I preserve the flags.
  • evanhevanh Posts: 15,192
    You wouldn't use _RET_ then. I still think it was one of those bad choices made.

  • Cluso99Cluso99 Posts: 18,069
    edited 2020-05-30 04:13
    Yes, I use _RET_ all the time. I just know it does not overwrite (ie pop) the c&z flags on return.

    You win some and lose some on the roundabout. I use both, probably equally in number.

    In fact what would have been nicer is if the standard RET [wc/wz/wcz] could also have had an option [sc/sz/scz/cc/cz/ccz] so that the c and/or z flags could also be cleared/set. Though preceding with MODCZ is easy enough.
  • evanhevanh Posts: 15,192
    It certainly would have been good if those that wanted a return status via flag were required to use the full RET.

    I basically never use _RET_ now.

  • Ah, thanks. Yes, both cases are useful from time to time. Float_Cmp() for example can return flags so they can be used immediately without checking the result (number), first.

    And BTW, can somebody please point me to the document where the arguments to MODCZ are explained? I know there are some predefined constants so I don't have to use binary literals. But I forgot them...
  • evanhevanh Posts: 15,192
    They used to be in instructions.txt file with PNut. They've been moved to the end of the main prop2 google doc now.
  • Cluso99Cluso99 Posts: 18,069
    MODCZ _set,_clr wcz
    sets C (ie C) and clears Z (ie NZ)
Sign In or Register to comment.