VETUS PARS RETRO CHIP TESTER TEST CODE WRITING MANUAL 1. Introduction The Vetus Pars Retro Chip Tester uses an interpreted instruction system. Every chip test is written as a list of instructions, one per line, each consisting of: OPCODE ARG1 ARG2 ARG3 The Vetus GUI software converts these text instructions into 32-bit program words and uploads them to the device. The Vetus Pars then executes the instructions to test the chip installed in the ZIF socket. End users may write their test scripts manually using any text editor they prefer (Notepad, TextEdit, Sublime, VS Code, etc.), as long as they follow the formatting rules described here. However, the Vetus GUI will insert opcode values automatically if they select instructions from the provided menus. 2. Required Tools Two things are required to develop or test chip scripts: 1. The Vetus GUI software • Used to upload new chip definitions, images, metadata, and test code. • Used to run tests interactively while developing a script. 2. A plain text editor (optional) • If users prefer to write tests manually. • The GUI can load and import these files. 3. File Format for Test Scripts A test script is a plain text file containing: 1. A header line: META: 2. A second header: CODE: 3. Lines of instructions: OPCODE ARG1 ARG2 ARG3 - please note that even if the argument is not used you must use 0x0 at least when using each opcode. For instance, if you use ENDTEST which takes no arguments, you still need to add all three arguments. Ex: ENDTEST 0x0 0x0 0x0 The GUI software will validate and convert this into program code automatically. 4. Opcode Byte Values Each instruction corresponds to a single opcode byte (the low byte of the first program word). Here are the opcodes and their byte values: SETPIN: 0x01 SETIN: 0x02 SETOUT: 0x09 RDPIN: 0x03 MULTIO: 0x05 MULTII: 0x06 MULTIHI: 0x07 MULTILO: 0x08 ASAFE: 0x0B GOSTRT: 0x0D ALLDIR: 0x0E ALLEVEL: 0x0F DEFADDR: 0x22 SETADDR: 0x21 ADDRBIT: 0x20 ADDRCLR: 0x2 LOOP: 0x10 ENDLOOP: 0x11 BRKLOOP: 0x13 DELUS: 0x16 DELMS: 0x17 WHILE: 0x18 ENDWHL: 0x19 JMP: 0x1A DOUNTIL: 0x1B ENDUNTIL: 0x1C CLKST: 0x1D CLKSTP: 0x1E IF: 0x50 ENDIF: 0x51 LEDON: 0x6C LEDOFF: 0x6D REGLOD: 0x40 REGCLR: 0x41 REGINC: 0x42 REGDEC: 0x43 ADD: 0x44 SUBTR: 0x45 MULT: 0x46 DIV: 0x47 RNG: 0x49 AND: 0x4A OR: 0x4B SHL: 0x4C SHR: 0x4D NOT: 0x4E XOR: 0x4F BTNPR: 0x6A BTNWT: 0x6B FILSCR: 0x61 SHOSTR: 0x60 TXTCOL: 0x63 PROG: 0x64 UDSCRN: 0x6F PASSFAIL: 0xF2 ENDTEST: 0xF0 BLNKON: 0x68 BLNKOFF: 0x69 FANON: 0x24 ARRADD: 0x25 ARRGET: 0x26 GETADDR: 0x27 PHIZ: 0x28 TOGPIN: 0x29 PIN2ARR: 0x2A DEF8: 0x2B SET8: 0x2C GET8: 0x2D 5. Registers The Vetus Pars test engine has 32 registers named R0 through R31. To reference a register, prefix with “#”: #R0 #R1 #R2... and so forth up to 32 registers total. Registers hold numbers, loop counters, results from GETADDR, GET8, or values read from pins. In code, if you are getting a value from the register then you need to use #Rn where n is the register number. If you are doing anything to a register other then using its value then you should simply use the register number for the argument. 6. DEF8 / SET8 / GET8 Table System Many chips use lookup tables for writing or verifying patterns. DEF8 index value extra Defines an 8-bit entry. SET8 index value flags Writes a value to the DEF8 entry or to the chip pins depending on the definition. GET8 dstIndex srcIndex flags Reads from the table and stores the result in R(dstIndex). Example: DEF8 0x0 0x1020304 0x1011 SET8 0x2 0xF 0x1 GET8 0x2 0x2 0x0 7. Pin Control Instructions ALLDIR sets direction for all pins at once. ALLEVEL sets initial logic levels for output pins. SETPIN controls one pin at a time. DELUS waits for microseconds. DELMS waits for milliseconds. SETOUT sets a pin as output. SETIN sets the pin as input Example: SETPIN 0x8 0x1 0x0 DELUS 0x10 0x0 0x0 SETPIN 0x8 0x0 0x0 SETOUT 0x1 0x0 0x0 SETIN 0xA 0x0 0x0 8. Loops LOOP num. empty empty ENDLOOP ends the loop. The internal counter decreases automatically. Example: LOOP 0x10 0x0 0x0 SET8 0x2 0xF 0x1 ENDLOOP 0x0 0x0 0x0 Loops the code inside of it 16 times (0x10) 9. Conditionals IF condition value value ENDIF Example: IF 0x1 #R2 0xF PASSFAIL 0x0 0x0 0x0 ENDTEST 0x0 0x0 0x0 ENDIF This would mean, if register2 is NOT equal to 15 (0xF) 10. Display Output The tester has a built-in text display. Use these to show results or messages during testing: SHOSTR stringIndex x y UDSCRN 0x0 0x0 0x0 TXTCOL (if text color is supported in your firmware) Example: SHOSTR 0x0 0x0 0x30 UDSCRN 0x0 0x0 0x0 11. Finishing the Test Every program must end with ENDTEST in order to exit the test: ENDTEST 0x1 0x0 0x0 If PASSFAIL was set to 1 it will pass. Setting it to 0 for failure. 12. Full Example Test (Copy-Paste Friendly) Below is a complete example test similar to a DRAM walking pattern. No code box formatting is used so it can be copied directly. [chipfile] type = single [chips] [meta] name = 4164 RAM pins = 16 type = 1 imageIndex = 3 [code] PASSFAIL 0x1 0x0 0x0 ALLDIR 0x1FF 0x1FF 0x0 ALLEVEL 0x80 0x101 0x0 DEF8 0x0 0x1020304 0x1011 DEF8 0x1 0xF070605 0x0 DEF8 0x2 0xB0C0D0E 0x0 REGLOD 0x0 0x0 0x0 REGLOD 0x1 0x0 0x0 SETPIN 0x8 0x0 0x0 SETPIN 0x10 0x1 0x0 SET8 0x2 0xF 0x1 LOOP 0x100 0x0 0x0 SET8 0x2 0xF 0x1 ENDLOOP 0x0 0x0 0x0 SHOSTR 0x0 0x0 0x30 DELMS 0x2 0x0 0x0 UDSCRN 0x0 0x0 0x0 LOOP 0xF 0x0 0x0 SET8 0x0 #R0 1x0 SET8 0x1 #R1 0x1 SETPIN 0x10 0x0 0x0 DELUS 0x10 0x0 0x0 SETPIN 0x10 0x1 0x0 REGINC 0x1 0x0 0x0 ENDLOOP 0x0 0x0 0x0 SET8 0x2 0xFF 0x0 REGLOD 1x0 0x0 0x0 LOOP 0xF 0x0 0x0 SET8 0x1 #R1 0x1 GET8 0x2 0x2 0x0 IF 0x1 #R2 0xF PASSFAIL 0x0 0x0 0x0 ENDTEST 0x0 0x0 0x0 ENDIF 0x0 0x0 0x0 DELMS 0x1 0x0 0x0 REGINC 0x1 0x0 0x0 ENDLOOP 0x0 0x0 0x0 SHOSTR 0x1 0x0 0x48 DELMS 0x2 0x0 0x0 UDSCRN 0x0 0x0 0x0 ENDTEST 0x0 0x0 0x0 13. Uploading and Testing The GUI must be used for: uploading new chip metadata uploading pin maps uploading test code uploading images validating text scripts running test code on the device debugging test output in real-time The device imports scripts via USB through the Vetus GUI app. VETUS PARS — FULL ADDRESSING SYSTEM (WITH GETADDR) The Vetus Pars uses a flexible, universal addressing system because different chips handle addressing in different ways. Some have a full 16-bit bus (SRAM/EPROM), some are multiplexed (DRAM), some use small 3–8-bit “select lines” (decoders, multiplexers), and some only need simple bit-toggling. To support all of these, the tester implements three addressing systems: 1. DEFADDR / SETADDR / GETADDR / ADDRBIT — full 16-bit addressing 2. DEF8 / SET8 / GET8 — small 8-bit address groups 3. Manual per-pin control — for unconventional chips ____________________________________________________________ WHAT ADDRESSING ACTUALLY MEANS Addressing is simply a way to choose one item out of many. For example: In SRAM, the address pins A0–Axx select which memory cell to read. In EPROMs, the address chooses which byte is output on D0–D7. In DRAM, the address is split into row and column (multiplexed). In 74HC138, the inputs A/B/C select which output goes LOW. In a multiplexer like CD4051, the address selects which input is routed out. The Vetus Pars must therefore drive address pins very precisely. ____________________________________________________________ ADDRESS SYSTEM 1: 16-BIT ADDRESS BUS (DEFADDR / SETADDR / GETADDR / ADDRBIT) This is the main addressing system for large memory chips and structured logic. It supports a full 16-bit virtual address bus: A0 through A15. ⸻ HOW TO THINK ABOUT IT You tell the tester: Which chip pins are A0–A15 What value you want on those address lines What direction each pin should be (input or output) - As related to the tester. If the chip pin needs an input then you want to OUTPUT from the tester. The tester handles the ZIF mapping automatically based on the chip’s pin count (important!). ⸻ DEFADDR — Define Chip Pin Positions for A0–A15 Correct argument meaning: Argument 1 chooses LOW or HIGH address byte 0x0 = define A0–A7 0x8 = define A8–A15 Argument 2 = four packed chip pins for the first four address bits Argument 3 = four packed chip pins for the next four address bits Example of packed format for Arg2: 0x04030201 means: A0 = pin 1 A1 = pin 2 A2 = pin 3 A3 = pin 4 The important part: Each packed 32-bit value holds exactly 4 chip pin numbers, each of which must be 2-digit hex values. The tester uses the chip’s pin count from metadata to remap these automatically to ZIF pins. ⸻ SETADDR — Send a 16-Bit Address Arguments: Arg1 = number of bits to drive (2-8) Arg2 = address byte (0x00–0xFF) Arg3 = direction (0 for input, 1 for output) <~ Again: input or output to/from the Vetus Pars tester. SETADDR 0x8 0xFF 0X1 -> set the address to 255 output. Before reading from a chip: Set Arg3 = 0 (input mode) This avoids bus contention when the chip drives data lines. The read function automatically set the pins to input but it's preferred to add this anyway as a precaution. ⸻ GETADDR — Read the Current Address Bits Into a Register GETADDR reads the defined address lines that were configured using DEFADDR (or ADDRBIT) and places the resulting 8-bit value into one of the tester’s registers. Correct arguments: Arg1 = bit count (0–8), meaning how many address bits you want to read Arg2 = register number to store the result Arg3 = 0 (reserved, unused but must exist) The tester reads the physical chip pins, applies the DEFADDR mapping, and assembles the result into an 8-bit value stored in the register. Typical uses: Verify that a counter chip is producing address lines correctly Confirm the correct address appears after DRAM RAS/CAS strobes Debug address decode logic Detect stuck address pins Reading data from data pins ⸻ ADDRBIT — Define or Override One Address Bit Arguments: Arg1 = bit number (0–15) Arg2 = chip pin number ADDRBIT is useful for: Fixing one bad mapping Supporting weirdly pinned chips Dynamic reconfiguration Row/column testing in DRAM ________________________________________________________ ADDRESS SYSTEM 2: 8-BIT ADDRESS GROUPS (DEF8 / SET8 / GET8) DEF8 gives the tester fast, compact addressing banks used for many logic chips. This system is ideal for: 74HC138 74HC154 4051 multiplexers 74HC157 Many ALUs Small ROM lookup tables DRAM row/column high-level helpers ⸻ DEF8 — Define an 8-Bit Address Bank Arguments: Arg1 = index of the 8-bit bank Arg2 = chip pins for low nibble A0–A3 Arg3 = chip pins for high nibble A4–A7 The pins are in the same packed 32-bit format as DEFADDR. Each DEF8 bank is like a small “virtual port” that can be reused anywhere in the test. ⸻ SET8 — Drive an 8-Bit Value Onto the Bank Arguments: Arg1 = number of bits to write (0–8) Arg2 = value to output (0–255) Arg3 = direction (0=input, 1=output) Most common pattern: Set direction = 1 before writing Set direction = 0 before reading ⸻ GET8 — Read 8 Bits From a DEF8 Bank Into a Register Arguments: Arg1 = DEF8 index Arg2 = output register Arg3 = reserved (0) This: Reads the actual physical chip pins as mapped by DEF8 Packs them into a byte Stores them in a register Useful for: Testing counters Reading DRAM sense lines Reading multiplexer outputs Verifying correct logic state sequences _______________________________________________________ CHOOSING BETWEEN DEFADDR AND DEF8 Use DEFADDR / SETADDR / GETADDR when: Chip has more than 8 address pins You need true 16-bit addressing You are testing SRAM/EPROM/DRAM/large ROM You need classical A0–Axx behavior Use DEF8 / SET8 / GET8 when: Chip only has 2–8 address pins You are making repeated index lookups You want fast looping and compact test code You want simple nibble-based mapping ALLDIR AND ALLEVEL QUICK GUIDE ──────────────────────────────────── These two instructions handle all address/data/control pins at once using a single binary mask. They affect every defined pin in your chip’s metadata pin map. You express pin direction or pin level using a binary pattern such as: 0b00000000 0b11111111 0b10101010 0b00001111 0b00110011 Each bit corresponds to ONE chip pin with SideA (whole left side starting at pin 1) being argument1 and SideB (the pin higher numbers) being argument2. The pins go from top of the chip to the bottom of the chip for each side starting with the LSB (far right) Ex: 0b00000001 The 1 here would be pin #1. If we were doing SideB then 1 would be the highest numbered pin on the chip whatever number that happens to be. You can input these as HEX, Decimal or Binary. It is easier however to use binary as each bit represents a chip pin. Vetus GUI will automatically translate it to HEX, which is what it must be saved as. ──────────────────────────────────── SETTING ALL PIN DIRECTIONS (ALLDIR) Instruction meaning: ALLDIR sets whether each test pin is input (read) or output (drive). Binary meaning: 0 = Input (high-impedance, listening) 1 = Output (driving logic level) Example meaning: 0b00000000 Every pin is input (safe mode for first power-up) 0b11111111 Every pin is output (only safe if truly required) 0b11110000 Upper 4 pins output, lower 4 pins input When to use it: • Just before test begins to safely define pin roles • To switch bus between read cycles and write cycles • Before reading memory, all address pins should be outputs, data pins inputs SETTING ALL PIN LEVELS (ALLEVEL) Instruction meaning: ALLEVEL sets logic HIGH/LOW on every output pin defined in metadata. Binary meaning: 0 = logic LOW 1 = logic HIGH Example meanings: 0b00001111 Lower pins HIGH, upper pins LOW 0b10101010 Alternating pattern HIGH/LOW 0b11111111 All HIGH When to use: • Apply full address lines at once • Pre-charge DRAM • Enable control signals in a single step • Drive entire bus pattern for comparison, ALU chips, ROM selects, etc. SAFETY RULE When unsure, ALWAYS begin with: ALLDIR = 0b00000000 All pins high-Z input, nothing driven. Then selectively drive only what is required. Never set ALLDIR to all outputs against a powered chip unless you know every bus line is safe to assert simultaneously. PRACTICAL FLOW DURING TESTING Typical scan sequence: ALLDIR → 0b00000000 (all input, safe) or ALLSAFE (this sets every pin to HI-Z) ALLDIR → set address pins output, data pins input ALLEVEL → drive full address and control pattern Read data pins Change address pattern Repeat For write-capable memory: ALLDIR → set address + data pins output ALLEVEL → drive write data Pulse write enable Switch data pins back to input (ALLDIR) Read to verify WHY BINARY IS USED INSTEAD OF HEX Binary directly reflects physical bus states. You can visually see which pins are: 1 → driving logic high 0 → low or high-Z depending on DIR mode It prevents confusion and speeds debugging.