I would like to suggest some enhancements to your scripting language, so that the test source files can be more readable and maintainable.
This should help with adoption, enabling people to create more and more solid tests.
(I don't see how to add tests to the Back-bit tester or the Retro Chip Tester Professional (RCT), but if its possible, maybe other language tweaks could help conversion to the Vetus Pars??)
NOTE: I'm a senior programmer/architect and have created several programming languages. As for electronics, I'm an enthusiast with noob/novice skills, and I can imagine creating test scripts if the easy-to-understand examples/precedents and tools are available.
This is what I'd like to see added to your script source language:
1) Allow for extra whitespace, including blank lines between commands.
2) Allow indentation of code blocks for better readability.
3) Allow comments using the `#` character. Anything after a `#` on a line is ignored.
4) Allow missing parameters, assuming that each missing parameter is set to zero by default.
5) Allow an optional 'defines' section of C-type defines for constants (i.e. simple replacements).
6) Allow an optional 'defines' section of C-type defines for macros (i.e. more complex code reuse).
The easier it is to read & maintain the scripts, the more likely people will create them (lots of them!)
In addition, similar chip tests should look similar. Consider that maybe copying a similar chip's script, and changing some constants to have a script for a new chip. This "reuse" concept could be pushed farther, but would create more work, dependencies and friction for the developer & platform. I wouldn't suggest any more than take a nicely formatted script file, tweak the constants, and be done. The core content of the main files would still be same, and easy to understand or enhance by diffing them.
Since these are just ideas for pre-processing the source, your tokenizer/interpreter probably won't need any changes.
I know that #6 in particular is the "heavier lift", but you'll see below the value it provides.
Even something as complex as macro handling can probably be easily handled with an existing pre-processor executable or library since it's all pre-processed on the PC-side (and result given to your existing tokenizer).
As an example, I started with one of your scripts, touched up the whitespace, then let AI enhance it a bit more with defines.
The files below are to clarify the concepts. I haven't tried running them 🙂
File A: The current 74LS08 test script
File B: Applied enhancements 1-5
File C: Applied enhancements 1-6 (should look most clean & maintainable)
-AAron
=========================================================
=========================================================
File A: This is the current 74LS08 test script
=========================================================
=========================================================
[chipfile] type = single [chips] --- [meta] name = 74LS08 pins = 14 type = 4 imageIndex = 2 [code] ALLDIR 0x5B 0x37 0x0 ALLEVEL 0x0 0x1 0x0 REGLOD 0x0 0x1 0x0 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 SETPIN 0x1 0x0 0x0 SETPIN 0x2 0x1 0x0 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 0x2 #R1 0x1 SHOSTR 0x2 0x0 0x3C PASSFAIL 0x0 0x0 0x0 ENDIF 0x0 0x0 0x0 UDSCRN 0x0 0x0 0x0 DELMS 0x3E8 0x0 0x0 REGINC 0x0 0x0 0x0 SHOSTR 0x0 0x0 0x28 UDSCRN 0x0 0x0 0x0 DELMS 0x3E8 0x0 0x0 SHOSTR 0x1 0x0 0x3C DELMS 0x3E8 0x0 0x0 RDPIN 0x6 0x1 0x0 IF 0x3 #R1 0x0 PASSFAIL 0x0 0x0 0x0 SHOSTR 0x2 0x0 0x3C ENDIF 0x0 0x0 0x0 SETPIN 0x4 0x1 0x0 RDPIN 0x6 0x1 0x0 IF 0x3 #R1 0x0 PASSFAIL 0x0 0x0 0x0 SHOSTR 0x2 0x0 0x3C ENDIF 0x0 0x0 0x0 SETPIN 0x4 0x0 0x0 SETPIN 0x5 0x1 0x0 RDPIN 0x6 0x1 0x0 IF 0x3 #R1 0x0 PASSFAIL 0x0 0x0 0x0 SHOSTR 0x2 0x0 0x3C ENDIF 0x0 0x0 0x0 SETPIN 0x4 0x1 0x0 RDPIN 0x6 0x1 0x0 IF 0x2 #R1 0x1 SHOSTR 0x2 0x0 0x3C PASSFAIL 0x0 0x0 0x0 ENDIF 0x0 0x0 0x0 UDSCRN 0x0 0x0 0x0 DELMS 0x3E8 0x0 0x0 REGINC 0x0 0x0 0x0 SHOSTR 0x0 0x0 0x28 UDSCRN 0x0 0x0 0x0 DELMS 0x3E8 0x0 0x0 SHOSTR 0x1 0x0 0x3C DELMS 0x3E8 0x0 0x0 RDPIN 0x8 0x1 0x0 IF 0x3 #R1 0x0 PASSFAIL 0x0 0x0 0x0 SHOSTR 0x2 0x0 0x3C ENDIF 0x0 0x0 0x0 SETPIN 0x9 0x1 0x0 RDPIN 0x8 0x1 0x0 IF 0x3 #R1 0x0 PASSFAIL 0x0 0x0 0x0 SHOSTR 0x2 0x0 0x3C ENDIF 0x0 0x0 0x0 SETPIN 0x9 0x0 0x0 SETPIN 0xA 0x1 0x0 RDPIN 0x8 0x1 0x0 IF 0x3 #R1 0x0 PASSFAIL 0x0 0x0 0x0 SHOSTR 0x2 0x0 0x3C ENDIF 0x0 0x0 0x0 SETPIN 0x9 0x1 0x0 RDPIN 0x8 0x1 0x0 IF 0x2 #R1 0x1 PASSFAIL 0x0 0x0 0x0 SHOSTR 0x2 0x0 0x3C ENDIF 0x0 0x0 0x0 UDSCRN 0x0 0x0 0x0 DELMS 0x3E8 0x0 0x0 REGINC 0x0 0x0 0x0 SHOSTR 0x0 0x0 0x28 UDSCRN 0x0 0x0 0x0 DELMS 0x3E8 0x0 0x0 SHOSTR 0x1 0x0 0x3C DELMS 0x3E8 0x0 0x0 RDPIN 0xB 0x1 0x0 IF 0x3 #R1 0x0 PASSFAIL 0x0 0x0 0x0 SHOSTR 0x2 0x0 0x3C ENDIF 0x0 0x0 0x0 SETPIN 0xC 0x1 0x0 RDPIN 0xB 0x1 0x0 IF 0x3 #R1 0x0 PASSFAIL 0x0 0x0 0x0 SHOSTR 0x2 0x0 0x3C ENDIF 0x0 0x0 0x0 SETPIN 0xC 0x0 0x0 SETPIN 0xD 0x1 0x0 RDPIN 0xB 0x1 0x0 IF 0x3 #R1 0x0 PASSFAIL 0x0 0x0 0x0 SHOSTR 0x2 0x0 0x3C ENDIF 0x0 0x0 0x0 SETPIN 0xC 0x1 0x0 RDPIN 0xB 0x1 0x0 IF 0x2 #R1 0x1 PASSFAIL 0x0 0x0 0x0 SHOSTR 0x2 0x0 0x3C ENDIF 0x0 0x0 0x0 UDSCRN 0x0 0x0 0x0 DELMS 0x3E8 0x0 0x0 ENDTEST 0x0 0x0 0x0 [strings] 0=checking gate %d #R0 1=gate %d #R0 good 2=gate %d #R0 bad 3= 4= 5= 6= 7= [ENDCHIPS]
=========================================================
=========================================================
File B: Applying enhancements 1-5, the test becomes
=========================================================
=========================================================
[chipfile] type = single [chips] --- [meta] name = 74LS08 pins = 14 type = 4 imageIndex = 2 #------------------------------------------------------------ # Constant definitions and symbolic names #------------------------------------------------------------ [defines] #define DELAY_MS 0x3E8 #define STR_CHECKING 0 #define STR_GOOD 1 #define STR_BAD 2 #define LEVEL_LOW 0 #define LEVEL_HIGH 1 # Gate pin mappings (A, B -> Y) #define G1_A 0x1 #define G1_B 0x2 #define G1_Y 0x3 #define G2_A 0x4 #define G2_B 0x5 #define G2_Y 0x6 #define G3_A 0x9 #define G3_B 0xA #define G3_Y 0x8 #define G4_A 0xC #define G4_B 0xD #define G4_Y 0xB #------------------------------------------------------------ # Test code #------------------------------------------------------------ [code] # Configure all pins and logic levels ALLDIR 0x5B 0x37 ALLEVEL REGLOD PASSFAIL #============================================================ # Gate 1 test #============================================================ SHOSTR STR_CHECKING 0 0x28 UDSCRN DELMS DELAY_MS SHOSTR STR_GOOD RDPIN G1_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G1_A LEVEL_HIGH RDPIN G1_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G1_A SETPIN G1_B LEVEL_HIGH RDPIN G1_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G1_A LEVEL_HIGH RDPIN G1_Y IF 0x2 #R1 LEVEL_HIGH SHOSTR STR_BAD PASSFAIL ENDIF # Prepare for next gate UDSCRN DELMS DELAY_MS REGINC #============================================================ # Gate 2 test #============================================================ SHOSTR STR_CHECKING UDSCRN DELMS DELAY_MS SHOSTR STR_GOOD DELMS DELAY_MS RDPIN G2_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G2_A LEVEL_HIGH RDPIN G2_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G2_A SETPIN G2_B LEVEL_HIGH RDPIN G2_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G2_A LEVEL_HIGH RDPIN G2_Y IF 0x2 #R1 LEVEL_HIGH SHOSTR STR_BAD PASSFAIL ENDIF UDSCRN DELMS DELAY_MS REGINC #============================================================ # Gate 3 test #============================================================ SHOSTR STR_CHECKING UDSCRN DELMS DELAY_MS SHOSTR STR_GOOD DELMS DELAY_MS RDPIN G3_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G3_A LEVEL_HIGH RDPIN G3_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G3_A SETPIN G3_B LEVEL_HIGH RDPIN G3_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G3_A LEVEL_HIGH RDPIN G3_Y IF 0x2 #R1 LEVEL_HIGH PASSFAIL SHOSTR STR_BAD ENDIF UDSCRN DELMS DELAY_MS REGINC #============================================================ # Gate 4 test #============================================================ SHOSTR STR_CHECKING UDSCRN DELMS DELAY_MS SHOSTR STR_GOOD DELMS DELAY_MS RDPIN G4_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G4_A LEVEL_HIGH RDPIN G4_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G4_A SETPIN G4_B LEVEL_HIGH RDPIN G4_Y IF 0x3 #R1 PASSFAIL SHOSTR STR_BAD ENDIF SETPIN G4_A LEVEL_HIGH RDPIN G4_Y IF 0x2 #R1 LEVEL_HIGH PASSFAIL SHOSTR STR_BAD ENDIF UDSCRN DELMS DELAY_MS ENDTEST #------------------------------------------------------------ # User-visible strings #------------------------------------------------------------ [strings] 0 = checking gate %d #R0 1 = gate %d #R0 good 2 = gate %d #R0 bad 3 = 4 = 5 = 6 = 7 = [ENDCHIPS]
=========================================================
=========================================================
File C: Applying enhancements 1-6, the test becomes this
=========================================================
=========================================================
[chipfile]
type = single
[chips]
---
[meta]
name = 74LS08
pins = 14
type = 4
imageIndex = 2
#============================================================
# Constants and symbolic names
#============================================================
[defines]
#define DELAY_MS 0x3E8
#define STR_CHECKING 0
#define STR_GOOD 1
#define STR_BAD 2
#define HIGH 1
#define LOW 0
#============================================================
# Reusable macros
#============================================================
# Display "checking gate N" and pause
#define START_GATE() \
SHOSTR STR_CHECKING \
UDSCRN \
DELMS DELAY_MS \
SHOSTR STR_GOOD \
DELMS DELAY_MS
# Advance UI/register between gates
#define NEXT_GATE() \
UDSCRN \
DELMS DELAY_MS \
REGINC
# Fail if output does not match expected value
#define CHECK_OUT(pin, expected) \
RDPIN pin \
IF 0x2 #R1 expected \
PASSFAIL \
SHOSTR STR_BAD \
ENDIF
# Full AND-gate truth table test
# A=0 B=0 → Y=0
# A=1 B=0 → Y=0
# A=0 B=1 → Y=0
# A=1 B=1 → Y=1
#define TEST_AND_GATE(A, B, Y) \
SETPIN A LOW \
SETPIN B LOW \
CHECK_OUT(Y, LOW) \
\
SETPIN A HIGH \
CHECK_OUT(Y, LOW) \
\
SETPIN A LOW \
SETPIN B HIGH \
CHECK_OUT(Y, LOW) \
\
SETPIN A HIGH \
CHECK_OUT(Y, HIGH)
#============================================================
# Test code
#============================================================
[code]
# Initial hardware setup
ALLDIR 0x5B 0x37
ALLEVEL
REGLOD
PASSFAIL
#------------------------------------------------------------
# Gate 1 (pins 1,2 -> 3)
#------------------------------------------------------------
START_GATE()
TEST_AND_GATE(0x1, 0x2, 0x3)
NEXT_GATE()
#------------------------------------------------------------
# Gate 2 (pins 4,5 -> 6)
#------------------------------------------------------------
START_GATE()
TEST_AND_GATE(0x4, 0x5, 0x6)
NEXT_GATE()
#------------------------------------------------------------
# Gate 3 (pins 9,10 -> 8)
#------------------------------------------------------------
START_GATE()
TEST_AND_GATE(0x9, 0xA, 0x8)
NEXT_GATE()
#------------------------------------------------------------
# Gate 4 (pins 12,13 -> 11)
#------------------------------------------------------------
START_GATE()
TEST_AND_GATE(0xC, 0xD, 0xB)
# End of test
UDSCRN
DELMS DELAY_MS
ENDTEST
#============================================================
# User-visible strings
#============================================================
[strings]
0 = checking gate %d #R0
1 = gate %d #R0 good
2 = gate %d #R0 bad
3 =
4 =
5 =
6 =
7 =
[ENDCHIPS]
Oh well, it messed up some little bits of my whitespace, no matter how hard I tried to touch it up after the paste 🙄
BTW, I'm a new owner of a Vetus Pars, and hope to see it grow in community and chip support.
Yes, the problem with the whitespace I think is that it doesn't function as a good text editor and I've known that. I don't like it either. Let me go through a few things.
- Adding comments is coming next version. we'll just use the normal // I suspect.
- You can absolutely use white spaces between lines if you want. It gets ignored by the parser. I often use spaces.
- Allowing missing parameters - I agree with you it's just a matter of updating.
For your other ideas. Some were already in the works some not. I appreciate it very much though. I think mosts of your issues will be taken care of on the next release which will be soon.
By the way, I'm working on a pre-processing version that works without changes to your existing code.
You can consider it for ideas and embed what you want, and there may even remain a compelling reason to keep an pre-processing system on source files.
I'm playing around right now (even though I'm putting many hours into it). I'll be posting the result to help your efforts & adoption.
At the moment, this is what my base source file looks like for the 74LS08, and it is currently being preprocessed into a .chip file that is equivalent to the 74LS08.chip file you originally created.
[chipfile]
type = single
[chips]
---
[meta]
name = 74LS08
pins = 14
type = 4
imageIndex = 2
[defines]
#define DISPLAY_DELAY_MS 0x3E8
#define CHECKING_X 0x0
#define RESULT_X 0x10
#define STR_CHECKING 0x0
#define STR_GOOD 0x1
#define STR_BAD 0x2
#define _SETUP_AND_TEST_AND_GATE(src_pin1, src_pin2, dest_pin, checking_y, result_y) \
_DISPLAY_AND_PREPARE_TEST_MESSAGES(STR_CHECKING, CHECKING_X, checking_y, STR_GOOD, RESULT_X, result_y, DISPLAY_DELAY_MS); \
_TEST_AND_GATE(src_pin1, src_pin2, dest_pin, 1, STR_BAD, RESULT_X, result_y); \
_SCREEN_REDRAW(); \
_REG_INC(0x0);
[code]
#include "includes/stddefs.h"
#include "includes/stddisplay.h"
#include "includes/stdopcodes.h"
#include "includes/stdtests.h"
#include "includes/stdgatetests.h"
/*
NOTES:
#R0 : Displayed gate number
#R1 : Temp storage for reading pins
*/
_TEST_INIT()
// Initial setup of state and hardware
_REG_LOAD(0x0, 0x1);
_ALL_DIR(0x5B, 0x37);
_ALL_LEVEL(0x0, 0x1);
/*********************************************************
Gate 1 (pins 1,2 -> 3)
*******************************************************/
_SETUP_AND_TEST_AND_GATE(0x1, 0x2, 0x3, ROW1_Y, ROW2_Y)
/******************************************************
Gate 2 (pins 4,5 -> 6)
*******************************************************/
_SETUP_AND_TEST_AND_GATE(0x4, 0x5, 0x6, ROW3_Y, ROW4_Y)
/******************************************************
Gate 3 (pins 9,10 -> 8)
*******************************************************/
_SETUP_AND_TEST_AND_GATE(0x9, 0xA, 0x8, ROW5_Y, ROW6_Y)
/******************************************************
Gate 4 (pins 12,13 -> 11)
**********************************************************/
_SETUP_AND_TEST_AND_GATE(0xC, 0xD, 0xB, ROW7_Y, ROW8_Y)
// End of test
_TEST_DONE(DISPLAY_DELAY_MS);
[strings]
0 = checking gate %d #R0
1 = gate %d #R0 good
2 = gate %d #R0 bad
3 =
4 =
5 =
6 =
7 =
[ENDCHIPS]
Not sure why I needed to approve your post. I didn't change any user settings. Anyway, I'm actually finishing up on preprocessing myself though I don't think it will be as in depth as you are doing. What I have and what will be out in a few days or no longer than a week, a way to declare variables in written code and files. It's not really possible to get the variable name from Vetus without wasting code space. Right now each test can have up to 256 lines (I plan on maybe expanding it to 512 in the future if needed. I'm not sure it would be) so I don't think the trade off is worth it to have variable names saved to Vetus. But, I am also adding a function system and that does use names and can be called via its name but it will of course cost an Opcode line for using any of those new function opcodes. There aren't any parameters but it does help tidy up the code and reduce code if you know you need to do a series of actions more than once.
I have to keep it relatively basic because the stm32 has limited space for code and the testing code flash is allocated very precisely to save on wear and for less code usage. There are actually a lot of things I wanted to do that just wasn't worth using the space on. Like for instance, there was at one time a temp sensor that could be set to turn on the accessory line. It was all done and working but it took about 14KB worth of code. It was not worth it. So, there are a lot of things to think about and sometimes things I want to do just cant be done because of limitations.
Oh and an error check button was added too. I will probably add a check box to perform error checks before uploading to Vetus but as of right now it's just a button. Everything will be in the update notes and I'll probably include all the errors that get checked. Also, if you have a handle or name you'd like me to use I'd like to give you credit on the GUI somewhere for your insights. Thanks.