How does a test failure work?
I know PASSFAIL can be used to set the final status of 0x0 (fail) or 0x1 (pass)... and I know the test should start with a PASSFAIL 0x0
The chip tests you coded use IF statements to set PASSFAIL and perform a SHOSTR that displays a custom fail message. Then a moment later the screen clears and becomes the common red failure screen.
But according to the code, after that IF, the test continues.... so I think you have some non-obvious "code short circuiting" check points going on that looks for PASSFAIL failure state and chooses not to continue the test if the test has already failed? Hmmmm... though it feels like a bad coding practice... could PASSFAIL be set to 0x1, then set back to 0x0 without the test ending?
Q1: When is the PASSFAIL checked and test stopped?
Q2: Can my test leave ever the custom progress/pass/fail details on the screen or will green/red screen always replace my script's output?
Passfail is simply a way to tell the tester to switch to either the pass screen or the fail screen when the test ends. It is just a stored value of pass or fail. It gets set like any other operation, that is, each opcode is performed in order. You never need to set pass fail if you don't want to. It will autofail however if you don't set pass. In the tests I have made, I set it to pass automatically at the start. If something doesn't pass I set fail and leave it because even if something else passes later that part still failed. You aren't required to fail a test if you don't want to. Say you are testing two different things but you don't care if one of them fails, well, you can just have it show text that it failed and still keep it as passing if you want to. It's basically just a variable that will always fail unless you set it to pass.
Ultimately my question is about best practice for failing a test script.
I was working with your 4164 and 74LS08 scripts, and they handle errors differently.
That lead to my confusion about the failure pattern, the language itself, and I mistakenly started to wonder if there was some extra magic going on.
It makes sense that there is nothing special about the PASSFAIL... now that I see the differences in the two scripts.
For posterity, I'll point out the two approaches that you've coded.
Pattern "One ENDTEST" (checks show good/bad, set failure & continue, one ENDTEST at bottom)
The 74LS08.chip script checks all truth table variations for each of 4 logic gates, and displays "good" or "bad" strings for each gate... but never ends the test until the last line of the script. If we just wanted to know chip good/bad, the first failure could immediately ended the test.
```
[...]
PASSFAIL 0x1 0x0 0x0
SHOSTR 0x0 0x0 0x28
UDSCRN 0x0 0x0 0x0
DELMS 0x3E8 0x0 0x0
SHOSTR 0x1 0x0 0x3C
RDPIN 0x3 0x1 0x0
IF 0x3 #R1 0x0
PASSFAIL 0x0 0x0 0x0
SHOSTR 0x2 0x0 0x3C
ENDIF 0x0 0x0 0x0
SETPIN 0x1 0x1 0x0
RDPIN 0x3 0x1 0x0
IF 0x3 #R1 0x0
PASSFAIL 0x0 0x0 0x0
SHOSTR 0x2 0x0 0x3C
ENDIF 0x0 0x0 0x0
[...]
ENDTEST
```
Pattern "Multiple ENDTEST" (multiple checks of IF..PASSFAIL..ENDTEST..ENDIF)
The 4164.chip script has 2 loops and an inner IF condition that immediately ends the script on the first failure. If it were coded like the 74LS08.chip, it might count all the failures, NOT do an ENDTEST in the IF condition, showing counts and the last line would be ENDTEST.
```
PASSFAIL 0x1 0x0 0x0
[...]
RDPIN 0xE 0x2 0x0
SETPIN 0xF 0x1 0x0
SETPIN 0x4 0x1 0x0
IF 0x1 #R2 0x1
PASSFAIL 0x0 0x0 0x0
ENDTEST 0x0 0x0 0x0
ENDIF 0x0 0x0 0x0
[...]
ENDTEST
```
I like the "Multiple ENDTEST" pattern best.
... because I only care if the chip is good or bad (decide as quick as possible because I could be testing a pile of chips)
... plus managing/queuing the good & bad strings makes the script a little harder to read.
Yeah, your preferred method is what I would use if I had a lot of them to test but sometimes I just like to see what's going on. I did various patterns for some of the tests so that people could get a good idea of some different ways to set them up. A lot of it is preference but it could be useful too if there are different kinds of tests someone wants to run. Like some of the RAM tests are full all address tests which take a while. Some of them are very short only testing like only testing for unwanted bit switching in rows or columns. Those I did give different names to though for the most part. You're really going to like the functions. You only need to declare functions after ENDTEST and then anywhere above end test you just use CALL (name). No other arguments needed for functions.. Just FUNC name, ENDFUNC, CALL name. that's it. I have the OSX version done and just need to port it to Windows now. It should take me about a day or two.