I could go into a lengthy discussion about the pros and cons of using MCR instructions the way you have described. It would be a totally imbalanced discussion though, as I can't think of any "pros". Here's just a few "cons", I'll keep the list short...
1. Your code becomes hard to debug - rungs that look like they are evaluating as true have their outputs false. You might be OK with this, but bubba at 3 am is gonna think the processor is screwed.
2. When you look at your code, how do you know whether you are inside an MCR zone or not, and whether the MCR is active or not. You might know the best way to determine this, think about bubba again.
3. Code between the MCR opening and closing rungs
still gets executed. What a total waste of processing time.
4. Rung placement becomes critical. If you have to add rungs, you have to be careful where you put them, which means a lot of searching up and down the ladder for MCR instructions. At this point, bubba, who is used to making program edits, becomes a time-bomb !
Using MCRs to organise your code execution "modes" is not the way to go. It is marginally better to use JMPs and LBLs, since the code between the JMP & LBL
does not get executed, but now you have the problem that outputs in the JMP's zone will be left on.
JSR/SBR/RET is by far the best way to handle the situation you describe. However, you still have the problem of outpts being left on when you stop calling a subroutine file. Most people don't make their subroutine calls conditional because of these sorts of problems, however, there are a few techniques you can use if you don't want the subroutines scanned all the time.
One possibility is an "initialisation" subroutine that turns off ALL outputs, internal memory bits, etc. You call this subroutine every scan, then call the subroutine for the "mode" you are running. Your outputs will reflect the states set by the code you have executed, rather than the states left behind by code you are no longer calling. Programming in SFC language (Logix5000) gets round this by having a "post-scan", which executes the SFC block one more time after it is made false, simply to reset any non-retentive outputs.
Just have to make sure that i don't get bit by the non-retentive bit.
You will....
As for the list of "non-retentive" instructions, it is simply a case of looking at what will happen to an "output" type instruction (sits on the right-hand end of the rung) that sees a false rung, which an active MCR does, it makes all the rungs false in the MCR zone....
OTEs will write a 0 to the address
TONs will reset
RTOs will feeze
TOFs
will start timing !
CTU and CTD will count again the next time the rung is seen as true
FALs will reset (depends on the mode)
FSCs will reset (depends on the mode)
Also any ONS instructions will be reset.
but the customer has a notion that too many subroutines that are called one time only are also to be avoided
Get him to give you reasons why, IMHO it is not the case. It is considered good programming practice to limit code execution in this way, as it saves processor scan time, but you have to ensure you don't leave anything "on" or "true" when you stop calling a particular piece of code.
Whatever you decide to do, remember the golden rule "Thou shalt DOCUMENT thy code" - but of course that won't help bubba if he hasn't got the offline file.