Skip to main content

Basic Control & Jumps

This booklet covers the basic execution-control opcodes 0x000x0F and the dedicated pin-output / display-input opcodes 0x410x44: sequential execution, delays and timers, conditional jumps, subroutine calls, digital output, waiting for screen input and 7-segment display scanning.

Program lines are written as LINE INST OP-0 OP-1; operand interpretation modes, the unit code table and the port system table are defined once in Brief.

0x00 Nop (SKIP)​

Do nothing — the program counter simply moves on to the next line.

tip

0x00 can be used as a line-skipper: leaving a reserved blank line is helpful for later program modifications.

000  00  0000  0000
001 0F 0000 0000
info
OperandsValue/RangeRemark
P00~P110000 / 0000Don't care, ignored

0x01 Digital Output Write​

Write a level to a digital output pin. This opcode has two modes:

Port mode (P00 = 01, recommended) — write one level to one pin of any output-capable port, addressed as port<<4 | pin (see the port system table).

Legacy mode (P00 ≠ 01) — kept for compatibility with early v1 programs: the write value in P10P11 (its low 8 bits) goes directly to the 8-bit digital output register R26 (the Port1 LED network). P01 selects the target: FF writes all 8 bits at once, 00~07 writes only that bit.

caution

0x01 is not registered in the mnemonic system. For new programs use 0x41 JT / 0x42 DK instead — they do the same job with a clearer meaning.

000  01  0101  0010
001 02 03E8 0000
002 01 00FF 000F
003 0F 0000 0000

Line 000 (Port mode) sets Port1 Pin0 to HIGH; line 002 (legacy mode) writes 0x0F (binary b00001111) to the 8 Port1 pins. Lines are shown in instruction form in both tabs because this opcode has no mnemonic.

Port mode (P00 = 01)
OperandsValue/RangeRemark
P0001Port mode
P01any non-zeroLevel = 1 (HIGH)
00Level = 0 (LOW)
P1000~06Port number
P110~FPin number in the port
Legacy mode (P00 ≠ 01)
OperandsValue/RangeRemark
P0000Legacy mode
P01FFWrite the whole 8-bit value to R26 (Port1)
00~07Write only bit 0~7 of the value to R26
P10P110000~FFFF16-bit whole: write value (low 8 bits used)

0x02 Delay (YS)​

Hold the program counter for the specified time, then execute the next line.

tip

The delay value can be a literal value or a value stored in a register.

000  02  03E8  0000
001 02 0005 0003
002 02 0001 FF00
003 0F 0000 0000

Line 000: delay 1000 × 1 ms = 1 s (literal). Line 001: delay 5 × 1 s = 5 s (literal, unit code 3). Line 002: delay R01 × 1 ms (register addressing).

Literal addressing
OperandsValue/RangeRemark
P00P010000~FFFF16-bit whole: delay value
P1000Literal value
P1100~04, 10Unit code
Register addressing
OperandsValue/RangeRemark
P00P01—Invalid (ignored) in register addressing
P0100~FFRegister index holding the delay value
P10FFRegister addressing
P1100~04, 10Unit code

0x03 Timer (DS)​

Start a down-counting timer. The length is a literal or register value plus a unit code, exactly like 0x02 YS.

Setting the timer does not stop the program — the following lines keep executing while the timer counts down. When the count reaches zero, the timeout flag register R23 is set; the program must clear R23 itself (e.g. with 0x10 FZ).

000  10  0023  0000
001 03 0005 0003
002 01 0101 0010
003 0A 0823 0006
004 02 0064 0000
005 0E 0000 0003
006 01 0100 0010
007 0F 0000 0000

Clear the timeout flag R23, start a 5 × 1 s timer, turn Port1 Pin0 on while waiting, poll R23 every 100 ms, and switch the pin off when the timer times out.

info
OperandsValue/RangeRemark
P00P010000~FFFF16-bit whole: timer value (literal addressing)
P1000Literal value
FFRegister addressing (P01 = register index)
P1100~04, 10Unit code

0x04 Jump if Greater (DYZ)​

If the value in register x is greater than the value in register y, jump to the target line; otherwise continue with the next line.

The six conditional jumps 0x04~0x09 share one operand format:

Shared format of 0x04~0x09
OperandsValue/RangeRemark
P0000~FFRegister x (left side of the comparison)
P0100~FFRegister y (right side of the comparison)
P10P110000~01FF16-bit whole: target line
000  10  000A  0001
001 10 0005 0002
002 04 0102 0005
003 01 0100 0010
004 0E 0000 0006
005 01 0101 0010
006 0F 0000 0000

R01 = 10, R02 = 5. Because R01 > R02 the jump is taken and Port1 Pin0 is turned on.

0x05 Jump if Less (XYZ)​

If R[x] is less than R[y], jump to the target line; otherwise continue. Operand format is identical to 0x04.

000  10  0003  0001
001 10 0001 0002
002 05 0102 0005
003 02 0064 0000
004 0E 0000 0006
005 01 0101 0010
006 0F 0000 0000

R01 = 3 (remaining attempts), R02 = 1 (warning threshold). When R01 < R02 the warning LED is switched on.

0x06 Jump if Equal (DZ)​

If R[x] is equal to R[y], jump to the target line; otherwise continue. Operand format is identical to 0x04.

000  14  0001  0000
001 10 0001 0002
002 06 0102 0005
003 02 000A 0000
004 0E 0000 0000
005 01 0101 0010
006 0F 0000 0000

Read the 7 onboard buttons (Port0) into R01 every 10 ms; when R01 equals the button-0 mask 0001, turn the LED on.

0x07 Jump if Greater or Equal (DDZ)​

If R[x] is greater than or equal to R[y], jump to the target line; otherwise continue. Operand format is identical to 0x04.

000  10  0064  0001
001 10 003C 0002
002 07 0102 0005
003 01 0100 0010
004 0E 0000 0006
005 01 0101 0010
006 0F 0000 0000

R01 = 100 (score), R02 = 60 (pass line). Score ≥ 60 turns the LED on (pass).

0x08 Jump if Less or Equal (XDZ)​

If R[x] is less than or equal to R[y], jump to the target line; otherwise continue. Operand format is identical to 0x04.

000  10  0014  0001
001 10 0018 0002
002 08 0102 0005
003 01 0100 0010
004 0E 0000 0006
005 01 0101 0010
006 0F 0000 0000

R01 = 20 (measured temperature), R02 = 24 (heater-off threshold). Temperature ≤ 24 switches the heater relay (Port1 Pin0) on.

0x09 Jump if Not Equal (BDZ)​

If R[x] is not equal to R[y], jump to the target line; otherwise continue. Operand format is identical to 0x04.

000  14  0001  0000
001 10 0001 0002
002 09 0102 0005
003 01 0100 0010
004 0E 0000 0006
005 01 0101 0010
006 0F 0000 0000

Read the buttons into R01; whenever the pressed pattern differs from the button-0 mask, the LED is turned on.

0x0A Conditional Jump (TJZ)​

Compare the value of the dedicated compare register R00 with a selected register R[n] according to a condition code; if the condition holds, jump to the target line, otherwise continue.

info
OperandsValue/RangeRemark
P0001Condition: =
02Condition: ≠
03Condition: >
04Condition: <
05Condition: ≥
06Condition: ≤
07Condition: is zero (only R[n] is looked at)
08Condition: is not zero (only R[n] is looked at)
P0100~FFRegister n (right side of the comparison)
P10P110000~01FF16-bit whole: target line
caution

R00 is the compare-dedicated register (see Internal Registers): put the left-hand value into R00 first. For condition codes 07/08 the comparison with R00 is not performed — only whether R[n] itself is zero matters.

000  10  0032  0000
001 10 0032 0001
002 0A 0101 0005
003 01 0100 0010
004 0E 0000 0006
005 01 0101 0010
006 0F 0000 0000

R00 = 50, R01 = 50. Condition code 01 (equal): R00 = R01 holds, the jump is taken and the LED is turned on.

0x0B Port Jump (TZ)​

Read a port or a single pin; if the result reads 1, jump to the target line, otherwise continue.

Whole-port mode (P00 = 00)
OperandsValue/RangeRemark
P0000Whole-port mode
P0100~06Port number; any pin of the port reading 1 triggers the jump
P10P110000~01FF16-bit whole: target line
Single-pin mode (P00 = 01)
OperandsValue/RangeRemark
P0001Single-pin mode
P0100~6FPin address port<<4 | pin
P10P110000~01FF16-bit whole: target line
caution

Port0 (buttons) and Port3 (ADS1115 > 2.5 V = 1) are read-only and always readable. Port1 is bidirectional — reading it with 0x14 QS first switches it to input direction (see the port system table).

000  0B  0000  0003
001 02 000A 0000
002 0E 0000 0000
003 01 0101 0010
004 0F 0000 0000

Poll the whole Port0 every 10 ms; as soon as any button is pressed, turn Port1 Pin0 on.

0x0C Call Subroutine (DY)​

Interrupt the current flow and jump to a subroutine. The return address is pushed onto a stack with a depth of 16 levels, so Call + Return can be nested.

caution

The target line number is carried in OP-1 (P10P11), not in OP-0. The target subroutine must end with a 0x0D FH to come back to the line after the call.

000  01  0101  0010
001 0C 0000 0004
002 01 0100 0010
003 0F 0000 0000
004 02 0064 0001
005 0D 0000 0000

Turn the LED on, call the subroutine at line 004 (delay 100 × 10 ms = 1 s), and after the return turn the LED off.

info
OperandsValue/RangeRemark
P00P010000Don't care
P10P110000~01FF16-bit whole: first line of the subroutine

0x0D Return (FH)​

Leave the current subroutine and continue at the line after the 0x0C DY that called it.

caution

Must be used together with 0x0C. Every call path needs its own FH, otherwise the stack gets out of step.

info
OperandsValue/RangeRemark
P00~P110000 / 0000Don't care, ignored

See the example in 0x0C.

0x0E Jump (ZY)​

Jump to the target line unconditionally.

000  01  0101  0010
001 02 00C8 0001
002 01 0100 0010
003 02 00C8 0001
004 0E 0000 0000

A 2 s blink loop: the jump at line 004 goes back to line 000 forever.

info
OperandsValue/RangeRemark
P00P010000Don't care
P10P110000~01FF16-bit whole: target line

0x0F End (JS)​

Terminate the program; the system turns to the STOP state.

caution

Without an 0F line the program would keep running past the last written line until the end of program memory. Put an 0F at the end of every program.

000  01  0101  0010
001 02 0064 0000
002 0F 0000 0000
info
OperandsValue/RangeRemark
P00~P110000 / 0000Don't care, ignored

0x41 Set Output High (JT)​

Set the specified pin to 1 (HIGH). The pin is addressed as port<<4 | pin (see the port system table).

000  41  0000  0013
001 02 03E8 0000
002 42 0000 0013
003 02 03E8 0000
004 0E 0000 0000

Blink Port1 Pin3 at 1 Hz with the JT/DK pair.

info
OperandsValue/RangeRemark
P00P010000Don't care
P10P110000~006F16-bit whole: pin address port<<4 | pin; the specified pin outputs 1

0x42 Set Output Low (DK)​

Set the specified pin to 0 (LOW). The pin addressing is identical to 0x41 JT.

000  41  0000  0011
001 02 01F4 0000
002 42 0000 0011
003 02 01F4 0000
004 41 0000 0012
005 02 01F4 0000
006 42 0000 0012
007 02 01F4 0000
008 0E 0000 0000

An alternating flasher on Port1 Pin1 / Pin2.

info
OperandsValue/RangeRemark
P00P010000Don't care
P10P110000~006F16-bit whole: pin address port<<4 | pin; the specified pin outputs 0

0x43 Screen Input (SR)​

Wait for a number typed on the main screen. The execution mechanism is a suspend–reply process:

  1. When this line executes, the program counter is frozen at this line and the main screen pops up an input box.
  2. The user types a number and confirms.
  3. The reply is written into the target register and the program continues from the next line.
info
OperandsValue/RangeRemark
P00P010000~00FF16-bit whole: target register (write as 00, register index)
P10P110000~000316-bit whole: number base code

Number base code: 00 = HEX, 01 = DEC, 02 = OCT, 03 = BIN; any illegal value falls back to DEC.

000  10  0000  0001
001 43 0001 0001
002 01 0101 0010
003 0F 0000 0000

Line 001 suspends the program until a decimal number is entered on the screen; the number is stored in R01 and the LED is turned on afterwards.

0x44 7-Segment Scan (SSE)​

Drive one digit of the onboard 4-digit 7-segment display. One instruction performs a fixed three-step sequence inside a single line:

  1. Blank: Port2 = 0x0F — all four digit selectors go inactive, all digits go dark (kills ghosting).
  2. Set segments: the low 8 bits of the segment-code register are written to the Port1 segment lines.
  3. Select digit: Port2 = P11 (low 4 bits) — the target digit is selected.

Hardware convention: the 8 Port1 pins map to the segments as bit7 = a … bit0 = dp; the low 4 bits of Port2 go through 1 kΩ resistors to the PNP bases of the common-anode digit selectors (active LOW). Digit-select values: thousands = 0x0E, hundreds = 0x0D, tens = 0x0B, ones = 0x07.

tip

For the common-anode hardware the segment codes must be inverted (segment lights when its line is LOW) — produce them with 0x30 BMQD using P10 = 1. Spend one 0x02 YS 1 ms after each SSE: one digit costs SSE + YS = 2 lines, a full 4-digit frame takes ~8 ms (≈125 Hz refresh).

info
OperandsValue/RangeRemark
P00P010000~00FF16-bit whole: segment-code register index (its low 8 bits are output to Port1)
P10P110000~000F16-bit whole: digit-select value (low 4 bits → Port2)
000  10  003C  0001
001 30 0002 0010
002 11 0003 0002
003 15 0003 0008
004 10 00FF 0004
005 44 0004 000E
006 02 0001 0000
007 44 0004 000D
008 02 0001 0000
009 44 0003 000B
00A 02 0001 0000
00B 44 0002 0007
00C 02 0001 0000
00D 0E 0000 0005

Display the number 60 (R01) on the two rightmost digits:

  • Line 000 puts 60 into R01; line 001 converts it with BMQD (decimal split, P10 = 1 inverted for the common-anode display) — R02 = tens segments (high 8 bits) + ones segments (low 8 bits).
  • Line 002 copies R02 into R03, line 003 shifts R03 right by 8 bits (0x15 XHYW), so R03 alone carries the tens segments.
  • Line 004 fills R04 with 0xFF — all segment lines HIGH means all segments off, i.e. a blank digit.
  • Lines 005~00C scan the four digits (thousands/hundreds blank, tens, ones) at 2 ms per digit; line 00D loops the scan forever.