๐ Test Code Library
This file stores code examples that are being tested and verified.
Moon Phase Simulation (12-Position LED)โ
12 WS2812B LEDs arranged in a circle, simulating the moon's cycle from New Moon โ First Quarter โ Full Moon โ Last Quarter โ New Moon. LEDs use yellow light (R=77, G=77, B=00) with 4 brightness levels (77=High, 33=Medium, 11=Low, 00=Off). Each phase uses E5 batch instructions to set specific LED combinations to simulate realistic moon shape โ lit LEDs form a crescent/half/gibbous pattern rather than sequential lighting.
Core Opcodes: FZ (10) init ยท E5 batch set LED colors via registers ยท YS (02) delay ยท ZY (0E) unconditional jump
E5 Instruction Format: E5 OP00+OP01 OP10+OP11
- OP00: Starting register number
- OP01: 00=low byte, 01=high byte
- OP10: Starting LED number
- OP11: Number of LEDs to set
Register Plan:
| Register | Value | Purpose |
|---|---|---|
| R01 | 7700 | Yellow high-brightness R |
| R02 | 7700 | Yellow high-brightness G |
| R03 | 0000 | Yellow high-brightness B |
| R04 | 3300 | Yellow medium-brightness R |
| R05 | 3300 | Yellow medium-brightness G |
| R06 | 0000 | Yellow medium-brightness B |
| R07 | 1100 | Yellow low-brightness R |
| R08 | 1100 | Yellow low-brightness G |
| R09 | 0000 | Yellow low-brightness B |
| R10 | 0000 | Off R (black) |
| R11 | 0000 | Off G (black) |
| R12 | 0000 | Off B (black) |
| R20 | 0080 | Delay duration (80 cycles per phase) |
E5 Usage Examples:
| Command | Effect |
|---|---|
E5 0A01 000C | All LEDs off (R10-R12 high bytes, all 12 LEDs) |
E5 0101 0003 | LED0-LED2 high-brightness yellow |
E5 0401 0504 | LED5-LED8 medium-brightness yellow |
E5 0701 0B01 | LED11 low-brightness yellow |
12 Phase Cycle: New Moon โ Waxing Crescent โ First Quarter โ Waxing Gibbous โ Full Moon โ Waning Gibbous โ Last Quarter โ Waning Crescent โ New Moon. Each phase uses "all off first, then light specific LED groups with appropriate brightness" to simulate realistic moon phase shapes.
Click to expand/collapse Moon Phase Simulation code
- Mnemonic Form
- Instruction Form
========== Register Initialization (000-012) ==========
000 FZ 0001 7700 R01 = 7700 Yellow High-Brightness R
001 FZ 0002 7700 R02 = 7700 Yellow High-Brightness G
002 FZ 0003 0000 R03 = 0000 Yellow High-Brightness B
003 FZ 0004 3300 R04 = 3300 Yellow Medium-Brightness R
004 FZ 0005 3300 R05 = 3300 Yellow Medium-Brightness G
005 FZ 0006 0000 R06 = 0000 Yellow Medium-Brightness B
006 FZ 0007 1100 R07 = 1100 Yellow Low-Brightness R
007 FZ 0008 1100 R08 = 1100 Yellow Low-Brightness G
008 FZ 0009 0000 R09 = 0000 Yellow Low-Brightness B
009 FZ 000A 0000 R10 = 0000 Off (black) R
00A FZ 000B 0000 R11 = 0000 Off (black) G
00B FZ 000C 0000 R12 = 0000 Off (black) B
00C FZ 0014 0080 R20 = 0080 Delay duration per phase
============= Main Loop: 12 Phases (020-08A) =============
Pattern: [E5 all-off] โ [E5 light specific groups] โ [YS delay]
--- Phase 0: NEW MOON - All off ---
020 E5 0A01 000C All 12 LEDs off (R10-R12 high bytes)
021 YS 0020 FF00 Delay per R20
--- Phase 1: WAXING CRESCENT - LED0 low yellow ---
022 E5 0A01 000C All off first (clear canvas)
023 E5 0701 0001 LED0 low-brightness yellow (R07-R09)
024 YS 0020 FF00 Delay
--- Phase 2: WAXING CRESCENT - LED0-LED1 medium yellow ---
025 E5 0A01 000C All off first
026 E5 0401 0002 LED0-LED1 medium yellow (R04-R06)
027 YS 0020 FF00 Delay
--- Phase 3: FIRST QUARTER - LED0-LED2 high yellow ---
028 E5 0A01 000C All off first
029 E5 0101 0003 LED0-LED2 high-brightness yellow (R01-R03)
02A YS 0020 FF00 Delay
--- Phase 4: WAXING GIBBOUS - LED0-LED4 high yellow ---
02B E5 0A01 000C All off first
02C E5 0101 0005 LED0-LED4 high-brightness yellow
02D YS 0020 FF00 Delay
--- Phase 5: WAXING GIBBOUS - LED0-LED5 high yellow ---
02E E5 0A01 000C All off first
02F E5 0101 0006 LED0-LED5 high-brightness yellow
030 YS 0020 FF00 Delay
--- Phase 6: FULL MOON - LED0-LED11 all high yellow ---
031 E5 0101 000C All 12 LEDs high-brightness yellow
032 YS 0020 FF00 Delay (slightly longer for full moon)
--- Phase 7: WANING GIBBOUS - LED7-LED11 high yellow ---
033 E5 0A01 000C All off first
034 E5 0101 0705 LED7-LED11 high-brightness yellow
035 YS 0020 FF00 Delay
--- Phase 8: WANING GIBBOUS - LED8-LED11 high yellow ---
036 E5 0A01 000C All off first
037 E5 0101 0804 LED8-LED11 high-brightness yellow
038 YS 0020 FF00 Delay
--- Phase 9: LAST QUARTER - LED9-LED11 medium yellow ---
039 E5 0A01 000C All off first
03A E5 0401 0903 LED9-LED11 medium-brightness yellow
03B YS 0020 FF00 Delay
--- Phase 10: WANING CRESCENT - LED10-LED11 low yellow ---
03C E5 0A01 000C All off first
03D E5 0701 0A02 LED10-LED11 low-brightness yellow
03E YS 0020 FF00 Delay
--- Phase 11: WANING CRESCENT - LED11 low yellow ---
03F E5 0A01 000C All off first
040 E5 0701 0B01 LED11 low-brightness yellow
041 YS 0020 FF00 Delay
--- Loop back to start ---
042 ZY 0000 0020 Jump back to 020, infinite moon cycle
000 10 0001 7700 R01 = 7700 High-brightness yellow R
001 10 0002 7700 R02 = 7700 High-brightness yellow G
002 10 0003 0000 R03 = 0000 High-brightness yellow B
003 10 0004 3300 R04 = 3300 Medium-brightness yellow R
004 10 0005 3300 R05 = 3300 Medium-brightness yellow G
005 10 0006 0000 R06 = 0000 Medium-brightness yellow B
006 10 0007 1100 R07 = 1100 Low-brightness yellow R
007 10 0008 1100 R08 = 1100 Low-brightness yellow G
008 10 0009 0000 R09 = 0000 Low-brightness yellow B
009 10 000A 0000 R10 = 0000 Off (black) R
00A 10 000B 0000 R11 = 0000 Off (black) G
00B 10 000C 0000 R12 = 0000 Off (black) B
00C 10 0014 0080 R20 = 0080 Delay duration per phase
--- Phase 0: NEW MOON (020) ---
020 E5 0A01 000C All off
021 02 0020 FF00 Delay
--- Phase 1: WAXING CRESCENT (022) ---
022 E5 0A01 000C All off first
023 E5 0701 0001 LED0 low yellow
024 02 0020 FF00 Delay
--- Phase 2: WAXING CRESCENT (025) ---
025 E5 0A01 000C All off first
026 E5 0401 0002 LED0-LED1 medium yellow
027 02 0020 FF00 Delay
--- Phase 3: FIRST QUARTER (028) ---
028 E5 0A01 000C All off first
029 E5 0101 0003 LED0-LED2 high yellow
02A 02 0020 FF00 Delay
--- Phase 4: WAXING GIBBOUS (02B) ---
02B E5 0A01 000C All off first
02C E5 0101 0005 LED0-LED4 high yellow
02D 02 0020 FF00 Delay
--- Phase 5: WAXING GIBBOUS (02E) ---
02E E5 0A01 000C All off first
02F E5 0101 0006 LED0-LED5 high yellow
030 02 0020 FF00 Delay
--- Phase 6: FULL MOON (031) ---
031 E5 0101 000C All 12 LEDs high yellow
032 02 0020 FF00 Delay
--- Phase 7: WANING GIBBOUS (033) ---
033 E5 0A01 000C All off first
034 E5 0101 0705 LED7-LED11 high yellow
035 02 0020 FF00 Delay
--- Phase 8: WANING GIBBOUS (036) ---
036 E5 0A01 000C All off first
037 E5 0101 0804 LED8-LED11 high yellow
038 02 0020 FF00 Delay
--- Phase 9: LAST QUARTER (039) ---
039 E5 0A01 000C All off first
03A E5 0401 0903 LED9-LED11 medium yellow
03B 02 0020 FF00 Delay
--- Phase 10: WANING CRESCENT (03C) ---
03C E5 0A01 000C All off first
03D E5 0701 0A02 LED10-LED11 low yellow
03E 02 0020 FF00 Delay
--- Phase 11: WANING CRESCENT (03F) ---
03F E5 0A01 000C All off first
040 E5 0701 0B01 LED11 low yellow
041 02 0020 FF00 Delay
--- Loop ---
042 0E 0000 0020 Jump back to 020
Register Initialization (000-00C)โ
| Line | Opcode | Description |
|---|---|---|
| 000 | FZ 0001 7700 | R01 = 7700, high-brightness yellow R value |
| 001 | FZ 0002 7700 | R02 = 7700, high-brightness yellow G value |
| 002 | FZ 0003 0000 | R03 = 0000, high-brightness yellow B value |
| 003 | FZ 0004 3300 | R04 = 3300, medium-brightness yellow R value |
| 004 | FZ 0005 3300 | R05 = 3300, medium-brightness yellow G value |
| 005 | FZ 0006 0000 | R06 = 0000, medium-brightness yellow B value |
| 006 | FZ 0007 1100 | R07 = 1100, low-brightness yellow R value |
| 007 | FZ 0008 1100 | R08 = 1100, low-brightness yellow G value |
| 008 | FZ 0009 0000 | R09 = 0000, low-brightness yellow B value |
| 009 | FZ 000A 0000 | R10 = 0000, off (black) R value |
| 00A | FZ 000B 0000 | R11 = 0000, off (black) G value |
| 00B | FZ 000C 0000 | R12 = 0000, off (black) B value |
| 00C | FZ 0014 0080 | R20 = 0080, delay duration per phase |
12-Phase Moon Cycle (020-042)โ
Pattern: All-off (E5 0A01) โ Light specific LEDs (E5) โ Delay (YS) โ Next phase
| Phase | Lines | Description |
|---|---|---|
| 0 | 020-021 | New Moon โ all LEDs off |
| 1 | 022-024 | Waxing Crescent โ LED0 low yellow |
| 2 | 025-027 | Waxing Crescent โ LED0-LED1 medium yellow |
| 3 | 028-02A | First Quarter โ LED0-LED2 high yellow |
| 4 | 02B-02D | Waxing Gibbous โ LED0-LED4 high yellow |
| 5 | 02E-030 | Waxing Gibbous โ LED0-LED5 high yellow |
| 6 | 031-032 | Full Moon โ all 12 LEDs high yellow |
| 7 | 033-035 | Waning Gibbous โ LED7-LED11 high yellow |
| 8 | 036-038 | Waning Gibbous โ LED8-LED11 high yellow |
| 9 | 039-03B | Last Quarter โ LED9-LED11 medium yellow |
| 10 | 03C-03E | Waning Crescent โ LED10-LED11 low yellow |
| 11 | 03F-041 | Waning Crescent โ LED11 low yellow |
| Loop | 042 | ZY 0000 0020 โ jump back to 020, infinite cycle |
E5 Batch Instruction Referenceโ
| Example | Meaning |
|---|---|
E5 0A01 000C | Set 12 LEDs starting at LED0 with values from R10-R12 (high bytes): all off |
E5 0101 0006 | Set 6 LEDs starting at LED0 with values from R01-R03 (high bytes): high-brightness yellow |
E5 0401 0903 | Set 3 LEDs starting at LED9 with values from R04-R06 (high bytes): medium-brightness yellow |
E5 0701 0B01 | Set 1 LED starting at LED11 with values from R07-R09 (high bytes): low-brightness yellow |
12-LED Ring Clock (Hour Gradient + Minute PWM + Seconds Digital Output + PWM Fade)โ
Hardware: 12 WS2812B LEDs arranged in a circle (positions 00-0B, clockwise). LED00 = 12 o'clock, LED01 = 1 o'clock, ... LED0B = 11 o'clock. 4 additional mono-color LEDs on IO[7:4] for seconds sub-display. 4 PWM channels (R2A-R2D, range 0000-03E8) for minute/second smooth fade.
Display Logic:
- Hour Hand (Green): State range 0-71 (12 positions ร 6 brightness levels). Position = state/6, sub-level = state%6. Uses E4 instruction to set green channel: leaving LED fades from L5โL0, entering LED fades from L0โL5, creating a smooth gradient between two adjacent hour positions.
- Minute Hand (Blue): State range 0-59. Position = state/5 (which of 12 LED positions). Sub-step = state%5 (0-4 intermediate). Uses E4 to set blue channel at position LED (max brightness). Sets R2A-R2D PWM values (0000/0CCC/1999/2666/03E8) proportional to sub-step for smooth minute transition indication.
- Second Hand (Red): State range 0-59. Position = state/5. Sub-step = state%5. Uses E4 to set red channel at position LED. Sets digital output on IO[7:4] (00/01/03/07/0F) = 0/1/2/3/4 mono LEDs lit. Also uses PWM fade on the "just-lit" LED (value 0000โ03E8 proportional to sub-step) to create a visual fade-in effect.
Core Opcodes: 10 (FZ) init ยท 2D register divide by literal ยท 2E register mod literal ยท 11 register copy ยท E4 single LED RGB ยท 0x04/0x05 conditional jump ยท 0x0E unconditional jump ยท 0x02 delay ยท 0x13 registerโdigital port
Register Plan:
| Register | Purpose |
|---|---|
| R00 | Temporary / working register |
| R01 | Brightness L0 = 0000 |
| R02 | Brightness L1 = 1100 |
| R03 | Brightness L2 = 3300 |
| R04 | Brightness L3 = 5500 |
| R05 | Brightness L4 = 7700 |
| R06 | Brightness L5 = 9900 |
| R07 | Hour hand state (00-47) |
| R08 | Minute hand state (00-3B) |
| R09 | Second hand state (00-3B) |
| R0A | Divisor 6 (for hour) |
| R0B | Divisor 5 (for minute/second) |
| R0C | Temporary value (hour position) |
| R0D | Temporary value (minute position) |
| R0E | Temporary value (second position) |
| R0F | Temporary value (brightness index) |
| R10 | LED RGB value buffer |
| R20 | Delay duration (03E8 = 1 second) |
| R2A | PWM channel A output (minute) |
| R2B | PWM channel B output (minute) |
| R2C | PWM channel C output (minute fade) |
| R2D | PWM channel D output (second fade) |
Time Initialization Example (10:30:45):
- Hour state = (10 ร 6) + (30 / 12) = 60 + 2 = 3C hex... but simpler: directly set R07 = computed value. Hour position advances by 1 every 12 minutes (720s / 12 positions = 60s per state, but 6 brightness levels per position โ 10s per level). So hour state = (hour ร 6) + (minutes / 12). For 10:30: (10ร6)+2 = 62 = 3E.
- Minute state = 30 = 1E. Position 6 (LED06), sub-step 0.
- Second state = 45 = 2D. Position 9 (LED09), sub-step 0.
Click to expand/collapse 12-LED Ring Clock code
- Mnemonic Form
- Instruction Form
========== Register Initialization (000-023) ==========
000 FZ 0001 0000 R01 = 0000 Brightness L0 (off)
001 FZ 0002 1100 R02 = 1100 Brightness L1
002 FZ 0003 3300 R03 = 3300 Brightness L2
003 FZ 0004 5500 R04 = 5500 Brightness L3
004 FZ 0005 7700 R05 = 7700 Brightness L4
005 FZ 0006 9900 R06 = 9900 Brightness L5 (max)
006 FZ 000A 0006 R0A = 0006 Hour divisor = 6
007 FZ 000B 0005 R0B = 0005 Minute/second divisor = 5
008 FZ 0020 03E8 R20 = 03E8 Delay = 1 second per tick
========== TIME INITIALIZATION (009-00B) ==========
009 FZ 0007 003E R07 = 003E Hour state = 62 (10:30, position 10, level 2)
00A FZ 0008 001E R08 = 001E Minute state = 30 (position 6, sub-step 0)
00B FZ 0009 002D R09 = 002D Second state = 45 (position 9, sub-step 0)
========== Main Loop (010-023): Update โ Render โ Delay โ Loop ==========
010 FZ 0000 003B R00 = 003B Compare value for overflow check (59)
011 04 0009 0015 If R09 > 59: minute rollover, jump to minute increment
012 12 0009 0001 R09 += 1 Increment second state
013 DY 0030 0000 Call Hour Render
014 DY 0070 0000 Call Minute Render
015 DY 00B0 0000 Call Second Render
016 02 0020 FF00 Delay 1 second (use R20 as duration reference)
017 ZY 0000 0010 Jump back to 010, loop forever
--- Minute rollover handling (018-023) ---
018 FZ 0009 0000 R09 = 0000 Reset second state to 0
019 04 0008 0022 If R08 > 59: hour rollover, jump to hour increment
01A 12 0008 0001 R08 += 1 Increment minute state
01B 04 0007 0026 If R07 > 71: hour overflow, jump to hour reset
01C DY 0030 0000 Call Hour Render
01D DY 0070 0000 Call Minute Render
01E DY 00B0 0000 Call Second Render
01F 02 0020 FF00 Delay 1 second
020 ZY 0000 0010 Jump back to main loop
--- Hour rollover handling (021-023) ---
021 FZ 0008 0000 R08 = 0000 Reset minute state to 0
022 12 0007 0001 R07 += 1 Increment hour state
023 04 0007 0047 If R07 > 71: overflow reset
024 ZY 0000 001C Continue rendering at 01C
025 FZ 0007 0000 R07 = 0000 Reset hour to 0
026 ZY 0000 001C Continue rendering at 01C
========== Hour Hand Render (030-06F): Green gradient ==========
030 FZ 000C 0000 R0C = 0 Clear hour position
031 11 0000 0007 R00 = R07 Copy hour state to R00 for division
032 2D 0000 0006 R00 = R00/6 Get hour position (0-11) โ R00
033 11 000C 0000 R0C = R00 Save hour position to R0C
034 11 0000 0007 R00 = R07 Copy hour state for mod
035 2E 0000 0006 R00 = R00%6 Get brightness index (0-5)
036 11 000F 0000 R0F = R00 Save brightness index to R0F
037 06 0000 004A If R0F = 0: exact position, jump to bright-only mode
038 06 0001 004C If R0F = 1: jump to level 1 handler
039 06 0002 004E If R0F = 2: jump to level 2 handler
03A 06 0003 0050 If R0F = 3: jump to level 3 handler
03B 06 0004 0052 If R0F = 4: jump to level 4 handler
03C 06 0005 0054 If R0F = 5: jump to level 5 handler
03D ZY 0000 006E Fallback: return
--- Brightness level dispatch table (index 0 โ leaving LED L5, entering LED L0) ---
03E (not used, handled above)
--- Calculate leaving LED position = R0C (current position) ---
--- Calculate entering LED position = (R0C + 1) mod 12 ---
03F 12 000C 0001 R0C += 1 R0C = next position candidate
040 FZ 0000 000B R00 = 000B Compare with 11 (max valid position)
041 05 000C 0044 If R0C < 12 (R0C โค 11): positions valid, skip reset
042 FZ 000C 0000 R0C = 0 Reset entering position to 0
043 ZY 0000 0044 Continue
--- Now: R0C = entering position, leaving position = R0C - 1 stored in R0D ---
044 11 000D 000C R0D = R0C Backup entering position
045 12 000D 000B R0D = R0D + 11 ( = R0C - 1, overflow safe) โ actually need subtract
046 2B 000D 0001 R0D = R0D - 1 R0D = leaving position = entering - 1
047 05 000D 0049 If R0D < 12 (valid): skip wrap check
048 FZ 000D 000B R0D = 0B Wrap: leaving = position 11
049 ZY 0000 004A Continue to brightness dispatch
--- Brightness dispatch: R0F (0-5) determines leaving LED level L5-R0F and entering LED level R0F ---
04A FZ 0000 0000 [Level 0] leaving L5, entering L0 (exact position)
04B 11 0010 0006 R10 = R06 L5 for leaving LED
04C E4 0D00 1000 Leaving LED: Green=L5 (R0D=position, high byte = 00, low byte G=R10 high=99)
Note: E4 format is E4 [POS+R] [G+B]. Need rethinking.
04D FZ 0000 0000 placeholder
...
Note: The above E4 instruction format needs reworking. Using simplified direct LED addressing:
E4 format: `E4 [position nibble + R-value high byte] [G-value high byte + B-value high byte]`
Simplifying: Use fixed LED position numbers 00-0B and set RGB with E4 using literal values for each of 12 positions via jump table.
--- Revised Hour Hand Render: Compute position + brightness level, then use jump table (050-06F) ---
050 11 0000 0007 R00 = R07 hour state
051 2D 0000 0006 R00 = R00 / 6 position
052 11 000C 0000 R0C = R00 save position
053 11 0000 0007 R00 = R07
054 2E 0000 0006 R00 = R00 % 6 brightness level (0-5)
055 11 000F 0000 R0F = R00 save level
056 06 000C 0060 If position = 0 โ jump to LED00 handler
057 06 000C 0061 If position = 1 โ jump to LED01 handler
058 06 000C 0062 If position = 2 โ jump to LED02 handler
059 06 000C 0063 If position = 3 โ jump to LED03 handler
05A 06 000C 0064 If position = 4 โ jump to LED04 handler
05B 06 000C 0065 If position = 5 โ jump to LED05 handler
05C 06 000C 0066 If position = 6 โ jump to LED06 handler
05D 06 000C 0067 If position = 7 โ jump to LED07 handler
05E 06 000C 0068 If position = 8 โ jump to LED08 handler
05F 06 000C 0069 If position = 9 โ jump to LED09 handler
060 06 000C 006A If position = 10 โ jump to LED0A handler
061 06 000C 006B If position = 11 โ jump to LED0B handler
062 ZY 0000 006F Fallback return
--- LED position handlers 00-0B: Set leaving+entering LEDs with proper green levels (063-06B) ---
063 11 000D 000C Position-based logic continues...
...
06E 13 0010 0000 Output final value
06F FH 0000 0000 Return from hour render
========== Minute Hand Render (070-0AF): Blue LED + PWM ==========
...
0AF FH 0000 0000 Return from minute render
========== Second Hand Render (0B0-0FF): Red LED + Digital Output + PWM Fade ==========
...
0FF FH 0000 0000 Return from second render
000 10 0001 0000
001 10 0002 1100
002 10 0003 3300
003 10 0004 5500
004 10 0005 7700
005 10 0006 9900
006 10 000A 0006
007 10 000B 0005
008 10 0020 03E8
009 10 0007 003E
00A 10 0008 001E
00B 10 0009 002D
010 10 0000 003B
011 04 0009 0018
012 12 0009 0001
013 0C 0030 0000
014 0C 0070 0000
015 0C 00A0 0000
016 02 03E8 0000
017 0E 0000 0010
018 10 0009 0000
019 04 0008 0022
01A 12 0008 0001
01B 04 0007 0025
01C 0C 0030 0000
01D 0C 0070 0000
01E 0C 00A0 0000
01F 02 03E8 0000
020 0E 0000 0010
021 10 0008 0000
022 12 0007 0001
023 04 0007 0026
024 0E 0000 001C
025 10 0007 0000
026 0E 0000 001C
030 11 0000 0007
031 2D 0000 0006
032 11 000C 0000
033 11 0000 0007
034 2E 0000 0006
035 11 000F 0000
036 12 000C 0001
037 10 0000 000B
038 05 000C 003A
039 10 000C 0000
03A 11 000D 000C
03B 2B 000D 0001
03C 10 0000 000B
03D 05 000D 003F
03E 10 000D 000B
03F 0E 0000 0040
040 06 000F 004A
041 06 000F 004D
042 06 000F 0050
043 06 000F 0053
044 06 000F 0056
045 06 000F 0059
046 0E 0000 005E
047 0E 0000 005B
04A 10 0010 9900
04B 10 0011 0000
04C 0E 0000 005B
04D 10 0010 7700
04E 10 0011 1100
04F 0E 0000 005B
050 10 0010 5500
051 10 0011 3300
052 0E 0000 005B
053 10 0010 3300
054 10 0011 5500
055 0E 0000 005B
056 10 0010 1100
057 10 0011 7700
058 0E 0000 005B
059 10 0010 0000
05A 10 0011 9900
05B E5 0101 000C
05C E4 0D00 1000
05D E4 0C00 1100
05E 0D 0000 0000
070 11 0000 0008
071 2D 0000 0005
072 11 000D 0000
073 11 0000 0008
074 2E 0000 0005
075 11 000F 0000
076 E4 0D99 0000
077 06 000F 007F
078 06 000F 0084
079 06 000F 0089
07A 06 000F 008E
07B 06 000F 0093
07C 0E 0000 009F
07F 10 002A 0000
080 10 002B 0000
081 10 002C 0000
082 10 002D 0000
083 0E 0000 009F
084 10 002A 0CCC
085 10 002B 0000
086 10 002C 0000
087 10 002D 0000
088 0E 0000 009F
089 10 002A 1999
08A 10 002B 0CCC
08B 10 002C 0000
08C 10 002D 0000
08D 0E 0000 009F
08E 10 002A 2666
08F 10 002B 1999
090 10 002C 0CCC
091 10 002D 0000
092 0E 0000 009F
093 10 002A 03E8
094 10 002B 2666
095 10 002C 1999
096 10 002D 0CCC
097 0E 0000 009F
09F 0D 0000 0000
0A0 11 0000 0009
0A1 2D 0000 0005
0A2 11 000E 0000
0A3 11 0000 0009
0A4 2E 0000 0005
0A5 11 000F 0000
0A6 E4 0E99 0000
0A7 06 000F 00AF
0A8 06 000F 00B2
0A9 06 000F 00B5
0AA 06 000F 00B8
0AB 06 000F 00BB
0AC 0E 0000 00CF
0AF 10 0010 0000
0B0 10 002D 0000
0B1 0E 0000 00BE
0B2 10 0010 0001
0B3 10 002D 0CCC
0B4 0E 0000 00BE
0B5 10 0010 0003
0B6 10 002D 1999
0B7 0E 0000 00BE
0B8 10 0010 0007
0B9 10 002D 2666
0BA 0E 0000 00BE
0BB 10 0010 000F
0BC 10 002D 03E8
0BD 0E 0000 00BE
0BE 13 0010 0000
0CF 0D 0000 0000
Design Walkthrough & Bug Analysis
Click to expand detailed design explanation
Overall Architectureโ
The clock uses a state-driven render model with three independent hands:
| Hand | Register | Range | Update Trigger | Render Subroutine |
|---|---|---|---|---|
| Hour (green) | R07 | 0-71 (12 positions ร 6 brightness steps) | Every 60 minutes | 030-05E |
| Minute (blue) | R08 | 0-59 (12 positions ร 5 sub-steps) | Every 60 seconds | 070-09F |
| Second (red) | R09 | 0-59 (12 positions ร 5 sub-steps) | Every 1 second | 0A0-0CF |
Initialization (000-00B): Preload 6 brightness levels into R01-R06, set divisors (R0A=6, R0B=5), set PWM max (R20=03E8), and set initial time (R07=hour, R08=minute, R09=second).
Main Loop (010-026): Check if each hand overflows โ if yes, rollover and cascade to next hand โ call all three render subroutines โ delay 1 second โ loop.
Bug #1: Conditional Jump Instruction Format (CRITICAL)โ
Root cause of the 020-line stuck loop.
The 0x04/0x05/0x06 instructions compare R00 against a literal value, NOT an arbitrary register against R00:
04 [literal] [target] โ if R00 > literal, jump
05 [literal] [target] โ if R00 < literal, jump
06 [literal] [target] โ if R00 == literal, jump
What the code does (line 010-011):
010 FZ 0000 003B R00 = 59
011 04 0009 0018 โ if R00(59) > 9: jump to 018 โ ALWAYS TRUE!
What was intended: "If R09 > 59, jump to rollover"
Correct approach: Copy R09 to R00 first, then compare:
10 0000 003B R00 = 59 (threshold)
11 0000 0009 R00 = R09 (copy second state to R00)
04 003B 0018 if R00 > 59: jump to rollover
This same error affects ALL conditional jumps in the program (lines 011, 019, 01B, 023, 038, 03D, 040-045, 077-07B, 0A7-0AB).
Bug #2: Wrong Opcodes for Division/Remainder/Subtractionโ
| Used | Correct | Instruction |
|---|---|---|
2D | 1D | Division (R00 = R00 / R[reg]) |
2E | 1E | Remainder (R00 = R00 % R[reg]) |
2B | 12 10 | Decrement (12 with OP-00=10) |
Additionally, 1D/1E operate on two registers, not a register and a literal:
1D 00 [dest] 00 [src] โ R[dest] = R[dest] / R[src]
So 2D 0000 0006 (intended: R00 = R00 / 6) must be:
1D 00 00 00 0A R00 = R00 / R0A (where R0A = 6, preloaded)
Bug #3: E4 LED Position Cannot Use Register Valueโ
The E4 instruction takes a literal LED position in the first byte:
E4 [LED_ID + R] [G + B] โ set LED #LED_ID to (R, G, B)
Code like E4 0D00 1000 tries to set LED #0D (13), which doesn't exist (only 00-0B). The intent was to use the value stored in R0D as the LED position, but E4 does not support register-indirect addressing.
Workaround: Use a 12-way jump table to dispatch to hardcoded E4 instructions for each position:
06 0000 0050 if R00 == 0: jump to LED00 handler
06 0001 0053 if R00 == 1: jump to LED01 handler
... (12 entries)
050 E4 00XX XXXX hardcoded: LED00, R=R10_high, G=00, B=00
053 E4 01XX XXXX hardcoded: LED01, R=R10_high, G=00, B=00
This requires 12 jump entries + 12 E4 instructions per hand, significantly increasing code size.
Summary of Required Fixesโ
- Every conditional jump needs a preceding
11 0000 00XXto copy the target register to R00 - Division/remainder opcodes change from
2D/2Eto1D/1E, with register-to-register format - Subtraction changes from
2Bto12 10(decrement mode) - E4 LED position must be hardcoded via jump table, not register-indirect
- Estimated code size after fix: ~200+ lines (approaching the 256-line limit)
Seconds-Only Clock Demo (Step 1: Second Hand Only)โ
This is a simplified sub-project that implements only the second hand of the ring clock. It fixes all bugs found in the full clock version and serves as a stepping stone before adding minute and hour hands.
Hardware: 12 WS2812B LEDs (ring, 00-0B) + 4 mono-color LEDs on IO[7:4]
Behavior:
- Red second hand moves clockwise, 1 LED position per 5 seconds
- Position = second / 5 (0-11)
- Sub-step = second % 5 (0-4): controls 4 mono-color LEDs on IO[7:4]
- Sub-step 0: all 4 LEDs off (second hand lands exactly on a position)
- Sub-step 1: 1 LED on (IO4)
- Sub-step 2: 2 LEDs on (IO4-5)
- Sub-step 3: 3 LEDs on (IO4-6)
- Sub-step 4: 4 LEDs on (IO4-7)
Register Map:
| Register | Purpose | Range |
|---|---|---|
| R00 | Temp/comparison | - |
| R09 | Second state | 0-59 |
| R0B | Divisor (5) | 5 |
| R0C | LED position (current) | 0-11 |
| R0D | LED position (previous) | 0-11, init=255 |
| R0F | Sub-step | 0-4 |
| R10 | Digital output value | 00/10/30/70/F0 |
Key Fixes Applied:
- All conditional jumps (
04/06/09) compare R00 against literal/register โ copy target register to R00 first via11 - Division uses
1D(not2D), remainder uses1E(not2E), both register-to-register - LED position hardcoded via 12-way jump table (E4 does not support register-indirect)
- Anti-flicker: Track previous position in R0D; only extinguish+re-light LEDs when position changes (every 5s), skip LED update when position unchanged (4 out of 5 seconds)
- Mnemonic Form
- Instruction Code Form
=== Init (000-002) ===
000 FZ 000B 0005 R0B = 5 (divisor)
001 FZ 0009 0000 R09 = 0 (initial seconds, editable)
002 FZ 000D 00FF R0D = 255 (impossible position, forces first render)
=== Main Loop (010-015) ===
010 FZ 0000 0009 R00 = R09
011 04 003B 0017 If R00 > 59: jump to 017 (reset)
012 DY 0020 0000 Call Second Render subroutine
013 12 0009 0001 R09 += 1
014 YS 03E8 0000 Delay 1 second
015 ZY 0000 0010 Jump back to 010
=== Reset (017-018) ===
017 FZ 0009 0000 R09 = 0
018 ZY 0000 0012 Jump to 012 (render reset value)
=== Second Render Subroutine (020-080) ===
--- Compute position & sub-step (020-025) ---
020 FZ 0000 0009 R00 = R09
021 1D 0000 000B R00 = R00 / R0B (position)
022 FZ 000C 0000 R0C = position
023 FZ 0000 0009 R00 = R09
024 1E 0000 000B R00 = R00 % R0B (sub-step)
025 FZ 000F 0000 R0F = sub-step
--- Anti-flicker: check if position changed (026-027) ---
026 11 0000 000D R00 = R0D (previous position)
027 09 000C 0066 If R00 == R0C: jump to 066 (skip LED update)
--- Position changed: update previous & extinguish all (028-034) ---
028 11 000D 000C R0D = R0C (save new position)
029 CD 0000 0000 LED00 off
02A CD 0100 0000 LED01 off
02B CD 0200 0000 LED02 off
02C CD 0300 0000 LED03 off
02D CD 0400 0000 LED04 off
02E CD 0500 0000 LED05 off
02F CD 0600 0000 LED06 off
030 CD 0700 0000 LED07 off
031 CD 0800 0000 LED08 off
032 CD 0900 0000 LED09 off
033 CD 0A00 0000 LED10 off
034 CD 0B00 0000 LED11 off
--- Position jump table (035-041) ---
035 FZ 0000 000C R00 = R0C (position)
036 06 0000 0042 If pos=0: jump to LED00 handler
037 06 0001 0045 If pos=1: jump to LED01 handler
038 06 0002 0048 If pos=2: jump to LED02 handler
039 06 0003 004B If pos=3: jump to LED03 handler
03A 06 0004 004E If pos=4: jump to LED04 handler
03B 06 0005 0051 If pos=5: jump to LED05 handler
03C 06 0006 0054 If pos=6: jump to LED06 handler
03D 06 0007 0057 If pos=7: jump to LED07 handler
03E 06 0008 005A If pos=8: jump to LED08 handler
03F 06 0009 005D If pos=9: jump to LED09 handler
040 06 000A 0060 If pos=10: jump to LED10 handler
041 06 000B 0063 If pos=11: jump to LED11 handler
--- 12 position handlers (3 lines each: set LED + load sub-step + jump) ---
042 CD 0099 0000 LED00 = red (R=99)
043 FZ 0000 000F R00 = sub-step
044 ZY 0000 0067 Jump to digital output
045 CD 0199 0000 LED01 = red
046 FZ 0000 000F
047 ZY 0000 0067
048 CD 0299 0000 LED02 = red
049 FZ 0000 000F
04A ZY 0000 0067
04B CD 0399 0000 LED03 = red
04C FZ 0000 000F
04D ZY 0000 0067
04E CD 0499 0000 LED04 = red
04F FZ 0000 000F
050 ZY 0000 0067
051 CD 0599 0000 LED05 = red
052 FZ 0000 000F
053 ZY 0000 0067
054 CD 0699 0000 LED06 = red
055 FZ 0000 000F
056 ZY 0000 0067
057 CD 0799 0000 LED07 = red
058 FZ 0000 000F
059 ZY 0000 0067
05A CD 0899 0000 LED08 = red
05B FZ 0000 000F
05C ZY 0000 0067
05D CD 0999 0000 LED09 = red
05E FZ 0000 000F
05F ZY 0000 0067
060 CD 0A99 0000 LED10 = red
061 FZ 0000 000F
062 ZY 0000 0067
063 CD 0B99 0000 LED11 = red
064 FZ 0000 000F
065 ZY 0000 0067
--- Sub-step digital output (066-080) ---
066 FZ 0000 000F R00 = sub-step (reached when position unchanged)
067 06 0000 0076 If sub=0: all off
068 06 0001 0078 If sub=1: 1 LED on
069 06 0002 007A If sub=2: 2 LEDs on
06A 06 0003 007C If sub=3: 3 LEDs on
06B 06 0004 007E If sub=4: 4 LEDs on
06C ZY 0000 007F Default (should not reach)
076 FZ 0010 0000 R10 = 00 (all off)
077 ZY 0000 007F
078 FZ 0010 0010 R10 = 10 (IO4 on)
079 ZY 0000 007F
07A FZ 0010 0030 R10 = 30 (IO4-5 on)
07B ZY 0000 007F
07C FZ 0010 0070 R10 = 70 (IO4-6 on)
07D ZY 0000 007F
07E FZ 0010 00F0 R10 = F0 (IO4-7 all on)
07F SC 0010 0000 Output R10 to digital port
080 FH 0000 0000 Return
000 10 000B 0005
001 10 0009 0000
002 10 000D 00FF
010 11 0000 0009
011 04 003B 0017
012 0C 0020 0000
013 12 0009 0001
014 02 03E8 0000
015 0E 0000 0010
017 10 0009 0000
018 0E 0000 0012
020 11 0000 0009
021 1D 0000 000B
022 11 000C 0000
023 11 0000 0009
024 1E 0000 000B
025 11 000F 0000
026 11 0000 000D
027 09 000C 0066
028 11 000D 000C
029 E4 0000 0000
02A E4 0100 0000
02B E4 0200 0000
02C E4 0300 0000
02D E4 0400 0000
02E E4 0500 0000
02F E4 0600 0000
030 E4 0700 0000
031 E4 0800 0000
032 E4 0900 0000
033 E4 0A00 0000
034 E4 0B00 0000
035 11 0000 000C
036 06 0000 0042
037 06 0001 0045
038 06 0002 0048
039 06 0003 004B
03A 06 0004 004E
03B 06 0005 0051
03C 06 0006 0054
03D 06 0007 0057
03E 06 0008 005A
03F 06 0009 005D
040 06 000A 0060
041 06 000B 0063
042 E4 0099 0000
043 11 0000 000F
044 0E 0000 0067
045 E4 0199 0000
046 11 0000 000F
047 0E 0000 0067
048 E4 0299 0000
049 11 0000 000F
04A 0E 0000 0067
04B E4 0399 0000
04C 11 0000 000F
04D 0E 0000 0067
04E E4 0499 0000
04F 11 0000 000F
050 0E 0000 0067
051 E4 0599 0000
052 11 0000 000F
053 0E 0000 0067
054 E4 0699 0000
055 11 0000 000F
056 0E 0000 0067
057 E4 0799 0000
058 11 0000 000F
059 0E 0000 0067
05A E4 0899 0000
05B 11 0000 000F
05C 0E 0000 0067
05D E4 0999 0000
05E 11 0000 000F
05F 0E 0000 0067
060 E4 0A99 0000
061 11 0000 000F
062 0E 0000 0067
063 E4 0B99 0000
064 11 0000 000F
065 0E 0000 0067
066 11 0000 000F
067 06 0000 0076
068 06 0001 0078
069 06 0002 007A
06A 06 0003 007C
06B 06 0004 007E
06C 0E 0000 007F
076 10 0010 0000
077 0E 0000 007F
078 10 0010 0010
079 0E 0000 007F
07A 10 0010 0030
07B 0E 0000 007F
07C 10 0010 0070
07D 0E 0000 007F
07E 10 0010 00F0
07F 13 0010 0000
080 0D 0000 0000
Code size: 99 instruction lines (well within 256-line limit)
Anti-flicker mechanism: R0D tracks the previous LED position. On each render:
- If position unchanged (4 out of 5 seconds): jump directly to digital output (line 066), skip LED extinguish+re-light
- If position changed (every 5 seconds): extinguish all LEDs, light new position, update R0D
To set initial time: Modify line 001 to change R09 initial value (0-59). Example: 001 10 0009 002D sets seconds to 45.
Mode-Switching Clock Demo (Step 2: Second / Minute / Hour Toggle)โ
See the Step 1 section above for the basic anti-flicker second hand pattern. This mode-switching version extends it by adding:
- Button (R3F): Pressing cycles R14 through 0 (seconds) โ 1 (minutes) โ 2 (hours) โ 0
- R13 release flag: Prevents repeated toggles while button is held
- R0D reset on mode change: Forces LED redraw with new color on mode switch
- Three render subroutines: Same anti-flicker structure, red for seconds, green for minutes, blue for hours
- Continuous counting: R09 (sec), R0A (min), R0B (hour) all increment in background regardless of display mode
Button detection flow:
R3F==0 โ set R13=0 (ready for press)
R3F==1 AND R13==0 โ R14 += 1, if R14==3 reset to 0, set R13=1, set R0D=255 (force redraw)
R3F==1 AND R13==1 โ do nothing (already handled)
Color selection:
If R14==0 โ call red render (R09 for position/sub-step, LED color: red)
If R14==1 โ call green render (R0A for position/sub-step, LED color: green)
If R14==2 โ call blue render (R0B for position, minutes/12 for sub-step, LED color: blue)
Hour hand special handling: Hours are 0-11 (no /5 division needed for position). Sub-step is derived from minutes: 0-11min=sub0, 12-23min=sub1, 24-35min=sub2, 36-47min=sub3, 48-59min=sub4.
Register Map:
| Register | Purpose |
|---|---|
| R00 | Temporary/comparison |
| R09 | Seconds (0-59) |
| R0A | Minutes (0-59) |
| R0B | Hours (0-11) |
| R0C | Current LED position (0-11) |
| R0D | Previous position (anti-flicker) |
| R0F | Sub-step (0-4) |
| R10 | Digital IO output value |
| R13 | Button release flag |
| R14 | Display mode (0=sec, 1=min, 2=hour) |
Total line usage: ~384 lines (well under 512 limit)
Complete Instruction Code (Main Loop)โ
000 10 000B 0005 R0B = 5 (divisor for sec/min position calc)
001 10 0009 0000 R09 = 0 (seconds)
002 10 000A 0000 R0A = 0 (minutes)
003 10 000D 00FF R0D = 255 (prev position, force initial redraw)
004 10 0014 0000 R14 = 0 (mode: seconds display)
005 10 0013 0000 R13 = 0 (button release flag)
=== Button Detection (010-01F): Cycle mode 0โ1โ2โ0 ===
010 11 0000 003F R00 = R3F (button state)
011 09 0001 0014 If R00==1: jump to 014 (button is pressed)
012 10 0013 0000 R13 = 0 (button released, reset flag)
013 0E 0000 0020 Jump to mode select
014 11 0000 0013 R00 = R13 (check release flag)
015 09 0000 0017 If R00==0: jump to 017 (toggle mode now)
016 0E 0000 0020 Jump to mode select (already handled this press)
017 12 0014 0001 R14 += 1 (advance to next mode)
018 11 0000 0014 R00 = R14 (check if mode==3)
019 09 0003 001B If R00==3: jump to 01B (reset mode to 0)
01A 0E 0000 001C Jump to set release flag
01B 10 0014 0000 R14 = 0 (reset to mode 0)
01C 10 0013 0001 R13 = 1 (set release flag, prevent repeat)
01D 10 000D 00FF R0D = 255 (force LED redraw for new color)
=== Mode Select (020-02F): Route to correct color renderer ===
020 11 0000 0014 R00 = R14
021 09 0001 0026 If R00==1: jump to green (minutes)
022 09 0002 0029 If R00==2: jump to blue (hours)
--- Mode 0: Red Seconds ---
023 11 0000 0009 R00 = R09 (seconds for bounds check)
024 04 003B 002B If R00>59: skip (shouldn't happen)
025 0C 0040 0000 Call red seconds render (040)
026 0E 0000 0030 Jump to counting
--- Mode 1: Green Minutes ---
027 11 0000 000A R00 = R0A (minutes for bounds check)
028 0C 00A0 0000 Call green minutes render (0A0)
029 0E 0000 0030 Jump to counting
--- Mode 2: Blue Hours ---
02A 0C 0100 0000 Call blue hours render (100)
02B 0E 0000 0030 Jump to counting
=== Counting (030-03F): Advance time ===
030 12 0009 0001 Seconds += 1
031 11 0000 0009 R00 = R09
032 09 003C 0034 If R00==60: jump to minute increment
033 0E 0000 0038 Jump to delay
034 10 0009 0000 R09 = 0 (reset seconds)
035 12 000A 0001 Minutes += 1
036 11 0000 000A R00 = R0A
037 09 003C 0039 If R00==60: jump to hour increment
038 02 03E8 0000 Delay 1 second
039 0E 0000 0010 Loop back to button detection
03A 10 000A 0000 R0A = 0 (reset minutes)
03B 12 000B 0001 Hours += 1
03C 11 0000 000B R00 = R0B
03D 09 000C 003F If R00==12: jump to reset hours
03E 02 03E8 0000 Delay 1 second
03F 0E 0000 0010 Loop back
040 10 000B 0000 R0B = 0 (reset hours)
041 02 03E8 0000 Delay 1 second
042 0E 0000 0010 Loop back
Red seconds render subroutine (050-0B7): Uses R09/5 for position, R09%5 for sub-step. LED color = red (E4 xx99 0000).
Green minutes render subroutine (0C0-127): Uses R0A/5 for position, R0A%5 for sub-step. LED color = green (E4 0000 9900).
Blue hours render subroutine (130-197): Position = R0B directly (0-11, no /5 needed). Sub-step derived from minutes by comparing R0A against 12/24/36/48 thresholds. LED color = blue (E4 0000 0099).
Five-Color Running Light (12-Position LED)โ
12 WS2812B LEDs arranged in a circle, displaying a five-color running light effect in sequence. Each color lights LEDs one by one from LED00 to LED0B, holds briefly after all are lit, then extinguishes all and proceeds to the next color. Color order: White โ Red โ Yellow โ Green โ Blue. Each color component max is 0x33 to ensure not too bright.
Core Opcodes: FZ (10) init ยท CD (E4) light/extinguish LED ยท YS (02) delay ยท DY (0C) call subroutine ยท FH (0D) return ยท ZY (0E) unconditional jump
Color Parameters (CD instruction format: CD LED_ID+R G+B):
| Color | R | G | B | CD Example (LED00) |
|---|---|---|---|---|
| White | 33 | 33 | 33 | CD 0033 3333 |
| Red | 33 | 00 | 00 | CD 0033 0000 |
| Yellow | 33 | 33 | 00 | CD 0033 3300 |
| Green | 00 | 33 | 00 | CD 0000 3300 |
| Blue | 00 | 00 | 33 | CD 0000 0033 |
| Off | 00 | 00 | 00 | CD 0000 0000 |
Click to expand/collapse Five-Color Running Light code
- Mnemonic Form
- Instruction Form
000 FZ 0001 0000 R01 = 0, constant
001 FZ 0002 0001 R02 = 1, constant
============= Main Loop =============
010 DY 0020 0000 Call white running subroutine
011 DY 0040 0000 Call red running subroutine
012 DY 0060 0000 Call yellow running subroutine
013 DY 0080 0000 Call green running subroutine
014 DY 00A0 0000 Call blue running subroutine
015 ZY 0000 0010 Jump back to 010, loop forever
========== White Running (020-039) ==========
020 CD 0033 3333 LED00 white
021 YS 0080 0000 Delay
022 CD 0133 3333 LED01 white
023 YS 0080 0000 Delay
024 CD 0233 3333 LED02 white
025 YS 0080 0000 Delay
026 CD 0333 3333 LED03 white
027 YS 0080 0000 Delay
028 CD 0433 3333 LED04 white
029 YS 0080 0000 Delay
02A CD 0533 3333 LED05 white
02B YS 0080 0000 Delay
02C CD 0633 3333 LED06 white
02D YS 0080 0000 Delay
02E CD 0733 3333 LED07 white
02F YS 0080 0000 Delay
030 CD 0833 3333 LED08 white
031 YS 0080 0000 Delay
032 CD 0933 3333 LED09 white
033 YS 0080 0000 Delay
034 CD 0A33 3333 LED0A white
035 YS 0080 0000 Delay
036 CD 0B33 3333 LED0B white
037 YS 0200 0000 Hold after all lit
038 DY 00C0 0000 Call all-off subroutine
039 FH 0000 0000 Return
========== Red Running (040-059) ==========
040 CD 0033 0000 LED00 red
041 YS 0080 0000 Delay
042 CD 0133 0000 LED01 red
043 YS 0080 0000 Delay
044 CD 0233 0000 LED02 red
045 YS 0080 0000 Delay
046 CD 0333 0000 LED03 red
047 YS 0080 0000 Delay
048 CD 0433 0000 LED04 red
049 YS 0080 0000 Delay
04A CD 0533 0000 LED05 red
04B YS 0080 0000 Delay
04C CD 0633 0000 LED06 red
04D YS 0080 0000 Delay
04E CD 0733 0000 LED07 red
04F YS 0080 0000 Delay
050 CD 0833 0000 LED08 red
051 YS 0080 0000 Delay
052 CD 0933 0000 LED09 red
053 YS 0080 0000 Delay
054 CD 0A33 0000 LED0A red
055 YS 0080 0000 Delay
056 CD 0B33 0000 LED0B red
057 YS 0200 0000 Hold after all lit
058 DY 00C0 0000 Call all-off subroutine
059 FH 0000 0000 Return
========== Yellow Running (060-079) ==========
060 CD 0033 3300 LED00 yellow
061 YS 0080 0000 Delay
062 CD 0133 3300 LED01 yellow
063 YS 0080 0000 Delay
064 CD 0233 3300 LED02 yellow
065 YS 0080 0000 Delay
066 CD 0333 3300 LED03 yellow
067 YS 0080 0000 Delay
068 CD 0433 3300 LED04 yellow
069 YS 0080 0000 Delay
06A CD 0533 3300 LED05 yellow
06B YS 0080 0000 Delay
06C CD 0633 3300 LED06 yellow
06D YS 0080 0000 Delay
06E CD 0733 3300 LED07 yellow
06F YS 0080 0000 Delay
070 CD 0833 3300 LED08 yellow
071 YS 0080 0000 Delay
072 CD 0933 3300 LED09 yellow
073 YS 0080 0000 Delay
074 CD 0A33 3300 LED0A yellow
075 YS 0080 0000 Delay
076 CD 0B33 3300 LED0B yellow
077 YS 0200 0000 Hold after all lit
078 DY 00C0 0000 Call all-off subroutine
079 FH 0000 0000 Return
========== Green Running (080-099) ==========
080 CD 0000 3300 LED00 green
081 YS 0080 0000 Delay
082 CD 0100 3300 LED01 green
083 YS 0080 0000 Delay
084 CD 0200 3300 LED02 green
085 YS 0080 0000 Delay
086 CD 0300 3300 LED03 green
087 YS 0080 0000 Delay
088 CD 0400 3300 LED04 green
089 YS 0080 0000 Delay
08A CD 0500 3300 LED05 green
08B YS 0080 0000 Delay
08C CD 0600 3300 LED06 green
08D YS 0080 0000 Delay
08E CD 0700 3300 LED07 green
08F YS 0080 0000 Delay
090 CD 0800 3300 LED08 green
091 YS 0080 0000 Delay
092 CD 0900 3300 LED09 green
093 YS 0080 0000 Delay
094 CD 0A00 3300 LED0A green
095 YS 0080 0000 Delay
096 CD 0B00 3300 LED0B green
097 YS 0200 0000 Hold after all lit
098 DY 00C0 0000 Call all-off subroutine
099 FH 0000 0000 Return
========== Blue Running (0A0-0B9) ==========
0A0 CD 0000 0033 LED00 blue
0A1 YS 0080 0000 Delay
0A2 CD 0100 0033 LED01 blue
0A3 YS 0080 0000 Delay
0A4 CD 0200 0033 LED02 blue
0A5 YS 0080 0000 Delay
0A6 CD 0300 0033 LED03 blue
0A7 YS 0080 0000 Delay
0A8 CD 0400 0033 LED04 blue
0A9 YS 0080 0000 Delay
0AA CD 0500 0033 LED05 blue
0AB YS 0080 0000 Delay
0AC CD 0600 0033 LED06 blue
0AD YS 0080 0000 Delay
0AE CD 0700 0033 LED07 blue
0AF YS 0080 0000 Delay
0B0 CD 0800 0033 LED08 blue
0B1 YS 0080 0000 Delay
0B2 CD 0900 0033 LED09 blue
0B3 YS 0080 0000 Delay
0B4 CD 0A00 0033 LED0A blue
0B5 YS 0080 0000 Delay
0B6 CD 0B00 0033 LED0B blue
0B7 YS 0200 0000 Hold after all lit
0B8 DY 00C0 0000 Call all-off subroutine
0B9 FH 0000 0000 Return
========== All-Off Subroutine (0C0-0CC) ==========
0C0 CD 0000 0000 LED00 off
0C1 CD 0100 0000 LED01 off
0C2 CD 0200 0000 LED02 off
0C3 CD 0300 0000 LED03 off
0C4 CD 0400 0000 LED04 off
0C5 CD 0500 0000 LED05 off
0C6 CD 0600 0000 LED06 off
0C7 CD 0700 0000 LED07 off
0C8 CD 0800 0000 LED08 off
0C9 CD 0900 0000 LED09 off
0CA CD 0A00 0000 LED0A off
0CB CD 0B00 0000 LED0B off
0CC FH 0000 0000 Return
000 10 0001 0000
001 10 0002 0001
010 0C 0020 0000
011 0C 0040 0000
012 0C 0060 0000
013 0C 0080 0000
014 0C 00A0 0000
015 0E 0000 0010
020 E4 0033 3333
021 02 0080 0000
022 E4 0133 3333
023 02 0080 0000
024 E4 0233 3333
025 02 0080 0000
026 E4 0333 3333
027 02 0080 0000
028 E4 0433 3333
029 02 0080 0000
02A E4 0533 3333
02B 02 0080 0000
02C E4 0633 3333
02D 02 0080 0000
02E E4 0733 3333
02F 02 0080 0000
030 E4 0833 3333
031 02 0080 0000
032 E4 0933 3333
033 02 0080 0000
034 E4 0A33 3333
035 02 0080 0000
036 E4 0B33 3333
037 02 0200 0000
038 0C 00C0 0000
039 0D 0000 0000
040 E4 0033 0000
041 02 0080 0000
042 E4 0133 0000
043 02 0080 0000
044 E4 0233 0000
045 02 0080 0000
046 E4 0333 0000
047 02 0080 0000
048 E4 0433 0000
049 02 0080 0000
04A E4 0533 0000
04B 02 0080 0000
04C E4 0633 0000
04D 02 0080 0000
04E E4 0733 0000
04F 02 0080 0000
050 E4 0833 0000
051 02 0080 0000
052 E4 0933 0000
053 02 0080 0000
054 E4 0A33 0000
055 02 0080 0000
056 E4 0B33 0000
057 02 0200 0000
058 0C 00C0 0000
059 0D 0000 0000
060 E4 0033 3300
061 02 0080 0000
062 E4 0133 3300
063 02 0080 0000
064 E4 0233 3300
065 02 0080 0000
066 E4 0333 3300
067 02 0080 0000
068 E4 0433 3300
069 02 0080 0000
06A E4 0533 3300
06B 02 0080 0000
06C E4 0633 3300
06D 02 0080 0000
06E E4 0733 3300
06F 02 0080 0000
070 E4 0833 3300
071 02 0080 0000
072 E4 0933 3300
073 02 0080 0000
074 E4 0A33 3300
075 02 0080 0000
076 E4 0B33 3300
077 02 0200 0000
078 0C 00C0 0000
079 0D 0000 0000
080 E4 0000 3300
081 02 0080 0000
082 E4 0100 3300
083 02 0080 0000
084 E4 0200 3300
085 02 0080 0000
086 E4 0300 3300
087 02 0080 0000
088 E4 0400 3300
089 02 0080 0000
08A E4 0500 3300
08B 02 0080 0000
08C E4 0600 3300
08D 02 0080 0000
08E E4 0700 3300
08F 02 0080 0000
090 E4 0800 3300
091 02 0080 0000
092 E4 0900 3300
093 02 0080 0000
094 E4 0A00 3300
095 02 0080 0000
096 E4 0B00 3300
097 02 0200 0000
098 0C 00C0 0000
099 0D 0000 0000
0A0 E4 0000 0033
0A1 02 0080 0000
0A2 E4 0100 0033
0A3 02 0080 0000
0A4 E4 0200 0033
0A5 02 0080 0000
0A6 E4 0300 0033
0A7 02 0080 0000
0A8 E4 0400 0033
0A9 02 0080 0000
0AA E4 0500 0033
0AB 02 0080 0000
0AC E4 0600 0033
0AD 02 0080 0000
0AE E4 0700 0033
0AF 02 0080 0000
0B0 E4 0800 0033
0B1 02 0080 0000
0B2 E4 0900 0033
0B3 02 0080 0000
0B4 E4 0A00 0033
0B5 02 0080 0000
0B6 E4 0B00 0033
0B7 02 0200 0000
0B8 0C 00C0 0000
0B9 0D 0000 0000
0C0 E4 0000 0000
0C1 E4 0100 0000
0C2 E4 0200 0000
0C3 E4 0300 0000
0C4 E4 0400 0000
0C5 E4 0500 0000
0C6 E4 0600 0000
0C7 E4 0700 0000
0C8 E4 0800 0000
0C9 E4 0900 0000
0CA E4 0A00 0000
0CB E4 0B00 0000
0CC 0D 0000 0000
Register Initialization (000-001)โ
| Line | Opcode | Description |
|---|---|---|
| 000 | FZ 0001 0000 | R01 = 0, constant |
| 001 | FZ 0002 0001 | R02 = 1, constant |
Main Loop (010-015)โ
| Line | Opcode | Description |
|---|---|---|
| 010 | DY 0020 0000 | Call white running subroutine at 020 |
| 011 | DY 0040 0000 | Call red running subroutine at 040 |
| 012 | DY 0060 0000 | Call yellow running subroutine at 060 |
| 013 | DY 0080 0000 | Call green running subroutine at 080 |
| 014 | DY 00A0 0000 | Call blue running subroutine at 0A0 |
| 015 | ZY 0000 0010 | Jump back to 010, infinite loop |
White Running (020-039)โ
| Line | Opcode | Description |
|---|---|---|
| 020 | CD 0033 3333 | LED00 white (R=33, G=33, B=33) |
| 021 | YS 0080 0000 | Delay for visible running effect |
| 022-036 | CD LED33 3333 + YS | LED01-LED0B lit white one by one, each with delay |
| 037 | YS 0200 0000 | Hold after all 12 LEDs lit |
| 038 | DY 00C0 0000 | Call all-off subroutine at 0C0 |
| 039 | FH 0000 0000 | White running complete, return |
Red Running (040-059)โ
| Line | Opcode | Description |
|---|---|---|
| 040 | CD 0033 0000 | LED00 red (R=33, G=00, B=00) |
| 041 | YS 0080 0000 | Delay |
| 042-056 | CD LED33 0000 + YS | LED01-LED0B lit red one by one, each with delay |
| 057 | YS 0200 0000 | Hold after all lit |
| 058 | DY 00C0 0000 | Call all-off subroutine |
| 059 | FH 0000 0000 | Return |
Yellow Running (060-079)โ
| Line | Opcode | Description |
|---|---|---|
| 060 | CD 0033 3300 | LED00 yellow (R=33, G=33, B=00) |
| 061 | YS 0080 0000 | Delay |
| 062-076 | CD LED33 3300 + YS | LED01-LED0B lit yellow one by one, each with delay |
| 077 | YS 0200 0000 | Hold after all lit |
| 078 | DY 00C0 0000 | Call all-off subroutine |
| 079 | FH 0000 0000 | Return |
Green Running (080-099)โ
| Line | Opcode | Description |
|---|---|---|
| 080 | CD 0000 3300 | LED00 green (R=00, G=33, B=00) |
| 081 | YS 0080 0000 | Delay |
| 082-096 | CD LED00 3300 + YS | LED01-LED0B lit green one by one, each with delay |
| 097 | YS 0200 0000 | Hold after all lit |
| 098 | DY 00C0 0000 | Call all-off subroutine |
| 099 | FH 0000 0000 | Return |
Blue Running (0A0-0B9)โ
| Line | Opcode | Description |
|---|---|---|
| 0A0 | CD 0000 0033 | LED00 blue (R=00, G=00, B=33) |
| 0A1 | YS 0080 0000 | Delay |
| 0A2-0B6 | CD LED00 0033 + YS | LED01-LED0B lit blue one by one, each with delay |
| 0B7 | YS 0200 0000 | Hold after all lit |
| 0B8 | DY 00C0 0000 | Call all-off subroutine |
| 0B9 | FH 0000 0000 | Return |
All-Off Subroutine (0C0-0CC)โ
| Line | Opcode | Description |
|---|---|---|
| 0C0 | CD 0000 0000 | LED00 off |
| 0C1 | CD 0100 0000 | LED01 off |
| 0C2 | CD 0200 0000 | LED02 off |
| 0C3 | CD 0300 0000 | LED03 off |
| 0C4 | CD 0400 0000 | LED04 off |
| 0C5 | CD 0500 0000 | LED05 off |
| 0C6 | CD 0600 0000 | LED06 off |
| 0C7 | CD 0700 0000 | LED07 off |
| 0C8 | CD 0800 0000 | LED08 off |
| 0C9 | CD 0900 0000 | LED09 off |
| 0CA | CD 0A00 0000 | LED0A off |
| 0CB | CD 0B00 0000 | LED0B off |
| 0CC | FH 0000 0000 | All-off complete, return |
Five-Color Flowing Lights (E5 Instruction Optimized Version)โ
Turning off all LEDs with a single E5 instruction: This example builds on the original five-color flowing lights by replacing the 12 individual LED-off instructions with a single E5 instruction. E4 instructions are still used to light up individual LEDs for the flowing effect, while the E5 instruction uses RGB values stored in registers to set multiple LEDs at once โ reducing the turn-off operation from 12 instructions to just 1.
Core Instructions: FZ (10) Initialize Registers ยท E4 Set Single LED Color ยท E5 Batch Set LED Colors via Registers ยท YS (02) Delay ยท DY (0C) Call Subroutine ยท FH (0D) Return ยท ZY (0E) Unconditional Jump
E5 Instruction Reference:
| Parameter | Value | Description |
|---|---|---|
| OP00 | 03 | Starting register number (uses R03, R04, R05) |
| OP01 | 01 | 00 = use low byte, 01 = use high byte |
| OP10 | 00 | Starting LED number |
| OP11 | 0C | Number of LEDs (0C = 12) |
Format: E5 OP00+OP01 OP10+OP11 โ example: E5 0301 000C (uses R03-R05 high bytes, sets LED00-LED11)
Register Plan:
| Registers | Purpose |
|---|---|
| R00-R02 | Current color values (updated at runtime) |
| R03-R05 | All-zero values (used for turning LEDs off) |
Click to expand/collapse E5 Optimized Version Full Code
- Mnemonic Form
- Instruction Form
000 FZ 0000 0000 R00 = 0000 (Color R value - updated at runtime)
001 FZ 0001 0000 R01 = 0000 (Color G value - updated at runtime)
002 FZ 0002 0000 R02 = 0000 (Color B value - updated at runtime)
003 FZ 0003 0000 R03 = 0000 (Off value R=00)
004 FZ 0004 0000 R04 = 0000 (Off value G=00)
005 FZ 0005 0000 R05 = 0000 (Off value B=00)
============== Main Loop =============
010 DY 0020 0000 Call White Flowing Subroutine
011 DY 0040 0000 Call Red Flowing Subroutine
012 DY 0060 0000 Call Yellow Flowing Subroutine
013 DY 0080 0000 Call Green Flowing Subroutine
014 DY 00A0 0000 Call Blue Flowing Subroutine
015 ZY 0000 0010 Jump to 010, infinite loop
========== White Flowing (020-03D) ==========
020 FZ 0000 3333 R00 = 3333 (White R=33)
021 FZ 0001 3333 R01 = 3333 (White G=33)
022 FZ 0002 3333 R02 = 3333 (White B=33)
023 E4 0033 3333 LED00 White
024 YS 0080 0000 Delay
025 E4 0133 3333 LED01 White
026 YS 0080 0000 Delay
027 E4 0233 3333 LED02 White
028 YS 0080 0000 Delay
029 E4 0333 3333 LED03 White
02A YS 0080 0000 Delay
02B E4 0433 3333 LED04 White
02C YS 0080 0000 Delay
02D E4 0533 3333 LED05 White
02E YS 0080 0000 Delay
02F E4 0633 3333 LED06 White
030 YS 0080 0000 Delay
031 E4 0733 3333 LED07 White
032 YS 0080 0000 Delay
033 E4 0833 3333 LED08 White
034 YS 0080 0000 Delay
035 E4 0933 3333 LED09 White
036 YS 0080 0000 Delay
037 E4 0A33 3333 LED0A White
038 YS 0080 0000 Delay
039 E4 0B33 3333 LED0B White
03A YS 0200 0000 Hold after all lit
03B E5 0301 000C Turn off all 12 LEDs using R03-R05 (all zeros) in one shot (OP00=03, OP01=01 high-byte, OP10=00 start LED, OP11=0C total 12)
03C YS 0080 0000 Short pause after off
03D FH 0000 0000 White flowing complete, return
========== Red Flowing (040-05D) ==========
040 FZ 0000 3300 R00 = 3300 (Red R=33)
041 FZ 0001 0000 R01 = 0000 (Red G=00)
042 FZ 0002 0000 R02 = 0000 (Red B=00)
043 E4 0033 0000 LED00 Red
044 YS 0080 0000 Delay
045 E4 0133 0000 LED01 Red
046 YS 0080 0000 Delay
047 E4 0233 0000 LED02 Red
048 YS 0080 0000 Delay
049 E4 0333 0000 LED03 Red
04A YS 0080 0000 Delay
04B E4 0433 0000 LED04 Red
04C YS 0080 0000 Delay
04D E4 0533 0000 LED05 Red
04E YS 0080 0000 Delay
04F E4 0633 0000 LED06 Red
050 YS 0080 0000 Delay
051 E4 0733 0000 LED07 Red
052 YS 0080 0000 Delay
053 E4 0833 0000 LED08 Red
054 YS 0080 0000 Delay
055 E4 0933 0000 LED09 Red
056 YS 0080 0000 Delay
057 E4 0A33 0000 LED0A Red
058 YS 0080 0000 Delay
059 E4 0B33 0000 LED0B Red
05A YS 0200 0000 Hold after all lit
05B E5 0301 000C Turn off all LEDs in one shot
05C YS 0080 0000 Pause
05D FH 0000 0000 Return
========== Yellow Flowing (060-07D) ==========
060 FZ 0000 3300 R00 = 3300 (Yellow R=33)
061 FZ 0001 3300 R01 = 3300 (Yellow G=33)
062 FZ 0002 0000 R02 = 0000 (Yellow B=00)
063 E4 0033 3300 LED00 Yellow
064 YS 0080 0000 Delay
065 E4 0133 3300 LED01 Yellow
066 YS 0080 0000 Delay
067 E4 0233 3300 LED02 Yellow
068 YS 0080 0000 Delay
069 E4 0333 3300 LED03 Yellow
06A YS 0080 0000 Delay
06B E4 0433 3300 LED04 Yellow
06C YS 0080 0000 Delay
06D E4 0533 3300 LED05 Yellow
06E YS 0080 0000 Delay
06F E4 0633 3300 LED06 Yellow
070 YS 0080 0000 Delay
071 E4 0733 3300 LED07 Yellow
072 YS 0080 0000 Delay
073 E4 0833 3300 LED08 Yellow
074 YS 0080 0000 Delay
075 E4 0933 3300 LED09 Yellow
076 YS 0080 0000 Delay
077 E4 0A33 3300 LED0A Yellow
078 YS 0080 0000 Delay
079 E4 0B33 3300 LED0B Yellow
07A YS 0200 0000 Hold after all lit
07B E5 0301 000C Turn off all LEDs in one shot
07C YS 0080 0000 Pause
07D FH 0000 0000 Return
========== Green Flowing (080-09D) ==========
080 FZ 0000 0000 R00 = 0000 (Green R=00)
081 FZ 0001 3300 R01 = 3300 (Green G=33)
082 FZ 0002 0000 R02 = 0000 (Green B=00)
083 E4 0000 3300 LED00 Green
084 YS 0080 0000 Delay
085 E4 0100 3300 LED01 Green
086 YS 0080 0000 Delay
087 E4 0200 3300 LED02 Green
088 YS 0080 0000 Delay
089 E4 0300 3300 LED03 Green
08A YS 0080 0000 Delay
08B E4 0400 3300 LED04 Green
08C YS 0080 0000 Delay
08D E4 0500 3300 LED05 Green
08E YS 0080 0000 Delay
08F E4 0600 3300 LED06 Green
090 YS 0080 0000 Delay
091 E4 0700 3300 LED07 Green
092 YS 0080 0000 Delay
093 E4 0800 3300 LED08 Green
094 YS 0080 0000 Delay
095 E4 0900 3300 LED09 Green
096 YS 0080 0000 Delay
097 E4 0A00 3300 LED0A Green
098 YS 0080 0000 Delay
099 E4 0B00 3300 LED0B Green
09A YS 0200 0000 Hold after all lit
09B E5 0301 000C Turn off all LEDs in one shot
09C YS 0080 0000 Pause
09D FH 0000 0000 Return
========== Blue Flowing (0A0-0BD) ==========
0A0 FZ 0000 0000 R00 = 0000 (Blue R=00)
0A1 FZ 0001 0000 R01 = 0000 (Blue G=00)
0A2 FZ 0002 3300 R02 = 3300 (Blue B=33)
0A3 E4 0000 0033 LED00 Blue
0A4 YS 0080 0000 Delay
0A5 E4 0100 0033 LED01 Blue
0A6 YS 0080 0000 Delay
0A7 E4 0200 0033 LED02 Blue
0A8 YS 0080 0000 Delay
0A9 E4 0300 0033 LED03 Blue
0AA YS 0080 0000 Delay
0AB E4 0400 0033 LED04 Blue
0AC YS 0080 0000 Delay
0AD E4 0500 0033 LED05 Blue
0AE YS 0080 0000 Delay
0AF E4 0600 0033 LED06 Blue
0B0 YS 0080 0000 Delay
0B1 E4 0700 0033 LED07 Blue
0B2 YS 0080 0000 Delay
0B3 E4 0800 0033 LED08 Blue
0B4 YS 0080 0000 Delay
0B5 E4 0900 0033 LED09 Blue
0B6 YS 0080 0000 Delay
0B7 E4 0A00 0033 LED0A Blue
0B8 YS 0080 0000 Delay
0B9 E4 0B00 0033 LED0B Blue
0BA YS 0200 0000 Hold after all lit
0BB E5 0301 000C Turn off all LEDs in one shot
0BC YS 0080 0000 Pause
0BD FH 0000 0000 Return
000 10 0000 0000
001 10 0001 0000
002 10 0002 0000
003 10 0003 0000
004 10 0004 0000
005 10 0005 0000
010 0C 0020 0000
011 0C 0040 0000
012 0C 0060 0000
013 0C 0080 0000
014 0C 00A0 0000
015 0E 0000 0010
020 10 0000 3333
021 10 0001 3333
022 10 0002 3333
023 E4 0033 3333
024 02 0080 0000
025 E4 0133 3333
026 02 0080 0000
027 E4 0233 3333
028 02 0080 0000
029 E4 0333 3333
02A 02 0080 0000
02B E4 0433 3333
02C 02 0080 0000
02D E4 0533 3333
02E 02 0080 0000
02F E4 0633 3333
030 02 0080 0000
031 E4 0733 3333
032 02 0080 0000
033 E4 0833 3333
034 02 0080 0000
035 E4 0933 3333
036 02 0080 0000
037 E4 0A33 3333
038 02 0080 0000
039 E4 0B33 3333
03A 02 0200 0000
03B E5 0301 000C
03C 02 0080 0000
03D 0D 0000 0000
040 10 0000 3300
041 10 0001 0000
042 10 0002 0000
043 E4 0033 0000
044 02 0080 0000
045 E4 0133 0000
046 02 0080 0000
047 E4 0233 0000
048 02 0080 0000
049 E4 0333 0000
04A 02 0080 0000
04B E4 0433 0000
04C 02 0080 0000
04D E4 0533 0000
04E 02 0080 0000
04F E4 0633 0000
050 02 0080 0000
051 E4 0733 0000
052 02 0080 0000
053 E4 0833 0000
054 02 0080 0000
055 E4 0933 0000
056 02 0080 0000
057 E4 0A33 0000
058 02 0080 0000
059 E4 0B33 0000
05A 02 0200 0000
05B E5 0301 000C
05C 02 0080 0000
05D 0D 0000 0000
060 10 0000 3300
061 10 0001 3300
062 10 0002 0000
063 E4 0033 3300
064 02 0080 0000
065 E4 0133 3300
066 02 0080 0000
067 E4 0233 3300
068 02 0080 0000
069 E4 0333 3300
06A 02 0080 0000
06B E4 0433 3300
06C 02 0080 0000
06D E4 0533 3300
06E 02 0080 0000
06F E4 0633 3300
070 02 0080 0000
071 E4 0733 3300
072 02 0080 0000
073 E4 0833 3300
074 02 0080 0000
075 E4 0933 3300
076 02 0080 0000
077 E4 0A33 3300
078 02 0080 0000
079 E4 0B33 3300
07A 02 0200 0000
07B E5 0301 000C
07C 02 0080 0000
07D 0D 0000 0000
080 10 0000 0000
081 10 0001 3300
082 10 0002 0000
083 E4 0000 3300
084 02 0080 0000
085 E4 0100 3300
086 02 0080 0000
087 E4 0200 3300
088 02 0080 0000
089 E4 0300 3300
08A 02 0080 0000
08B E4 0400 3300
08C 02 0080 0000
08D E4 0500 3300
08E 02 0080 0000
08F E4 0600 3300
090 02 0080 0000
091 E4 0700 3300
092 02 0080 0000
093 E4 0800 3300
094 02 0080 0000
095 E4 0900 3300
096 02 0080 0000
097 E4 0A00 3300
098 02 0080 0000
099 E4 0B00 3300
09A 02 0200 0000
09B E5 0301 000C
09C 02 0080 0000
09D 0D 0000 0000
0A0 10 0000 0000
0A1 10 0001 0000
0A2 10 0002 3300
0A3 E4 0000 0033
0A4 02 0080 0000
0A5 E4 0100 0033
0A6 02 0080 0000
0A7 E4 0200 0033
0A8 02 0080 0000
0A9 E4 0300 0033
0AA 02 0080 0000
0AB E4 0400 0033
0AC 02 0080 0000
0AD E4 0500 0033
0AE 02 0080 0000
0AF E4 0600 0033
0B0 02 0080 0000
0B1 E4 0700 0033
0B2 02 0080 0000
0B3 E4 0800 0033
0B4 02 0080 0000
0B5 E4 0900 0033
0B6 02 0080 0000
0B7 E4 0A00 0033
0B8 02 0080 0000
0B9 E4 0B00 0033
0BA 02 0200 0000
0BB E5 0301 000C
0BC 02 0080 0000
0BD 0D 0000 0000
Register Initialization (000-005)โ
| Line | Instruction | Description |
|---|---|---|
| 000 | FZ 0000 0000 | R00 = 0000, Color R placeholder (updated at start of each subroutine) |
| 001 | FZ 0001 0000 | R01 = 0000, Color G placeholder |
| 002 | FZ 0002 0000 | R02 = 0000, Color B placeholder |
| 003 | FZ 0003 0000 | R03 = 0000, Off R value (fixed=00) |
| 004 | FZ 0004 0000 | R04 = 0000, Off G value (fixed=00) |
| 005 | FZ 0005 0000 | R05 = 0000, Off B value (fixed=00) |
Main Loop (010-015)โ
| Line | Instruction | Description |
|---|---|---|
| 010 | DY 0020 0000 | Call White flowing subroutine |
| 011 | DY 0040 0000 | Call Red flowing subroutine |
| 012 | DY 0060 0000 | Call Yellow flowing subroutine |
| 013 | DY 0080 0000 | Call Green flowing subroutine |
| 014 | DY 00A0 0000 | Call Blue flowing subroutine |
| 015 | ZY 0000 0010 | Jump back to 010, infinite loop |
Optimization Comparison: E5 Batch Off vs E4 Individual Offโ
| Method | Instruction Count | Example |
|---|---|---|
| E4 Individual Off (Original) | 12 instructions | E4 0000 0000 โ E4 0100 0000 โ ... โ E4 0B00 0000 |
| E5 Batch Off (Optimized) | 1 instruction | E5 0301 000C |
E5 Instruction Parameter Breakdownโ
Taking E5 0301 000C as example:
| Part | Value | Meaning |
|---|---|---|
| OP00 (first half of high byte) | 03 | Uses R03 as starting register |
| OP01 (second half of high byte) | 01 | Uses high byte of each register for color values |
| OP10 (first half of low byte) | 00 | Starts from LED00 |
| OP11 (second half of low byte) | 0C | Total 12 LEDs (0C=12) |
Color source: High byte of R03=00, R04=00, R05=00 โ RGB=(00,00,00) Black/off.
E5 Rotating LED Effect (Progressive On/Off)โ
Core Idea: Keep E5 instruction's OP10 (starting LED position) fixed at 00, and continuously change OP11 (LED count) to achieve two phases:
- Phase 1 (Waxing):
E5 0101 00NNโ light up N white LEDs from LED0, progressively expanding from 1 to 12 (progressive ON) - Phase 2 (Waning):
E5 0401 00NNโ overwrite with N black LEDs from LED0, progressively expanding from 0 to 12 (progressive OFF via black overwriting)
Meanwhile, use R20 register to store delay duration, and reference the register value through YS 0020 FF00 format delay instructions, enabling runtime-adjustable speed control.
Key Difference from Snake: The snake moves by changing OP10 (start position) with fixed OP11. This example keeps OP10 fixed at 00 and changes OP11 (count) โ the "rotating" effect emerges from progressively lighting and blacking out LEDs from the same origin.
E5 Instruction Parameter Changes (Rotating Version):
| Phase | OP00 | OP01 | OP10 | OP11 Range | Color Source | Effect |
|---|---|---|---|---|---|---|
| Progressive ON | 01 | 01 | 00 | 01โ0C | R01,R02,R03 high byte (white) | Light up 1โ12 LEDs from LED0 |
| Progressive OFF | 04 | 01 | 00 | 00โ0C | R04,R05,R06 high byte (black) | Overwrite 0โ12 LEDs with black |
Register Plan:
| Register | Value | Purpose |
|---|---|---|
| R20 | 0008 | Delay duration = 8ms (very fast flow, modifiable) |
| R01 | 1000 | White R value (high 8 bits = 10, dim white) |
| R02 | 1000 | White G value (high 8 bits = 10) |
| R03 | 1000 | White B value (high 8 bits = 10) |
| R04 | 0000 | Black R value (high 8 bits = 00, off) |
| R05 | 0000 | Black G value (high 8 bits = 00, off) |
| R06 | 0000 | Black B value (high 8 bits = 00, off) |
Click to expand/collapse Rotating LED Effect Full Code
- Mnemonic Form
- Instruction Form
000 FZ 0020 0008 R20 = 0008 (Delay = 8ms, very fast, modifiable for speed)
001 FZ 0001 1000 R01 = 1000 (White R = 10, high byte)
002 FZ 0002 1000 R02 = 1000 (White G = 10)
003 FZ 0003 1000 R03 = 1000 (White B = 10)
004 FZ 0004 0000 R04 = 0000 (Black R = 00)
005 FZ 0005 0000 R05 = 0000 (Black G = 00)
006 FZ 0006 0000 R06 = 0000 (Black B = 00)
========== Waxing Phase (010-027): LED count 1โ12, progressive ON ==========
010 E5 0101 0001 LED0 (1 LED) dim white (10,10,10)
011 YS 0020 FF00 Read delay from R20 (8ms)
012 E5 0101 0002 LED0-LED1 (2 LEDs)
013 YS 0020 FF00 Delay
014 E5 0101 0003 LED0-LED2 (3 LEDs)
015 YS 0020 FF00 Delay
016 E5 0101 0004 LED0-LED3 (4 LEDs)
017 YS 0020 FF00 Delay
018 E5 0101 0005 LED0-LED4 (5 LEDs)
019 YS 0020 FF00 Delay
01A E5 0101 0006 LED0-LED5 (6 LEDs)
01B YS 0020 FF00 Delay
01C E5 0101 0007 LED0-LED6 (7 LEDs)
01D YS 0020 FF00 Delay
01E E5 0101 0008 LED0-LED7 (8 LEDs)
01F YS 0020 FF00 Delay
020 E5 0101 0009 LED0-LED8 (9 LEDs)
021 YS 0020 FF00 Delay
022 E5 0101 000A LED0-LED9 (10 LEDs)
023 YS 0020 FF00 Delay
024 E5 0101 000B LED0-LED10 (11 LEDs)
025 YS 0020 FF00 Delay
026 E5 0101 000C LED0-LED11 (All 12 LEDs) fully lit
027 YS 0020 FF00 Delay
========== Waning Phase (029-042): LED count 0โ12 black overwrite, progressive OFF ==========
029 E5 0401 0000 0 LED black overwritten (no visible change, baseline)
02A YS 0020 FF00 Delay
02B E5 0401 0001 LED0 overwritten with black (1 LED off)
02C YS 0020 FF00 Delay
02D E5 0401 0002 LED0-LED1 overwritten with black (2 LEDs off)
02E YS 0020 FF00 Delay
02F E5 0401 0003 LED0-LED2 overwritten with black (3 LEDs off)
030 YS 0020 FF00 Delay
031 E5 0401 0004 LED0-LED3 overwritten with black (4 LEDs off)
032 YS 0020 FF00 Delay
033 E5 0401 0005 LED0-LED4 overwritten with black (5 LEDs off)
034 YS 0020 FF00 Delay
035 E5 0401 0006 LED0-LED5 overwritten with black (6 LEDs off)
036 YS 0020 FF00 Delay
037 E5 0401 0007 LED0-LED6 overwritten with black (7 LEDs off)
038 YS 0020 FF00 Delay
039 E5 0401 0008 LED0-LED7 overwritten with black (8 LEDs off)
03A YS 0020 FF00 Delay
03B E5 0401 0009 LED0-LED8 overwritten with black (9 LEDs off)
03C YS 0020 FF00 Delay
03D E5 0401 000A LED0-LED9 overwritten with black (10 LEDs off)
03E YS 0020 FF00 Delay
03F E5 0401 000B LED0-LED10 overwritten with black (11 LEDs off)
040 YS 0020 FF00 Delay
041 E5 0401 000C LED0-LED11 overwritten with black (All 12 off, all dark)
042 YS 0020 FF00 Delay
043 ZY 0000 0010 Jump back to 010, restart LED rotation cycle
000 10 0020 0008
001 10 0001 1000
002 10 0002 1000
003 10 0003 1000
004 10 0004 0000
005 10 0005 0000
006 10 0006 0000
010 E5 0101 0001
011 02 0020 FF00
012 E5 0101 0002
013 02 0020 FF00
014 E5 0101 0003
015 02 0020 FF00
016 E5 0101 0004
017 02 0020 FF00
018 E5 0101 0005
019 02 0020 FF00
01A E5 0101 0006
01B 02 0020 FF00
01C E5 0101 0007
01D 02 0020 FF00
01E E5 0101 0008
01F 02 0020 FF00
020 E5 0101 0009
021 02 0020 FF00
022 E5 0101 000A
023 02 0020 FF00
024 E5 0101 000B
025 02 0020 FF00
026 E5 0101 000C
027 02 0020 FF00
029 E5 0401 0000
02A 02 0020 FF00
02B E5 0401 0001
02C 02 0020 FF00
02D E5 0401 0002
02E 02 0020 FF00
02F E5 0401 0003
030 02 0020 FF00
031 E5 0401 0004
032 02 0020 FF00
033 E5 0401 0005
034 02 0020 FF00
035 E5 0401 0006
036 02 0020 FF00
037 E5 0401 0007
038 02 0020 FF00
039 E5 0401 0008
03A 02 0020 FF00
03B E5 0401 0009
03C 02 0020 FF00
03D E5 0401 000A
03E 02 0020 FF00
03F E5 0401 000B
040 02 0020 FF00
041 E5 0401 000C
042 02 0020 FF00
043 0E 0000 0010
Instruction Notesโ
The core pattern uses two different register color sources to build the rotation effect:
| Instruction Group | Purpose |
|---|---|
E5 0101 00NN | Using R01-R03 (dim white) as color, light up N LEDs starting from LED0 |
E5 0401 00NN | Using R04-R06 (black/off) as color, overwrite N LEDs starting from LED0 |
YS 0020 FF00 | Read delay from R20 (8ms), controls rotation speed |
Visual Effect: The first half (010โ027) "grows" a white light bar from left to right across all 12 LEDs. The second half (029โ042) then "erases" it from the left using black overwrites โ creating a clean wipe-style rotating flow.
E5 Instruction Parameter Comparison Table (Rotating Version)โ
| Phase | Lines | OP00 | OP01 | OP10 | OP11 Range | Color | Effect |
|---|---|---|---|---|---|---|---|
| Waxing (ON) | 010โ026 | 01 | 01 | 00 | 01โ0C | White (R01-R03) | 1โ12 LEDs progressive ON from left |
| Waning (OFF) | 029โ041 | 04 | 01 | 00 | 00โ0C | Black (R04-R06) | 0โ12 LEDs progressive black overwrite from left |
Register-based Delay + E5 Waterfall Light (Changing OP11 Count, R20 Stores Duration)โ
Core Idea: Keep E5 instruction's OP10 (starting LED position) fixed at 00, and continuously change OP11 (LED count) to achieve sequential lighting on and off from left to right. Meanwhile, use R20 register to store delay duration, and reference the register value through YS 0020 FF00 format delay instructions, enabling runtime-adjustable speed control.
YS Instruction Register Mode:
| Instruction | OP-0 | OP-1 | Description |
|---|---|---|---|
YS 03E8 0000 | 03E8(immediate) | 0000(ms) | Standard mode: delay 1000ms |
YS 0020 FF00 | 0020(R20) | FF+unit | Register mode: FF means read duration from R20, low byte 00 means unit ms |
Register Plan:
| Register | Value | Purpose |
|---|---|---|
| R20 | 0080 | Delay duration = 128ms (modifiable at runtime, adjusts waterfall speed) |
| R01 | 3300 | Color R value (high byte = 33) |
| R02 | 3300 | Color G value (high byte = 33) |
| R03 | 3300 | Color B value (high byte = 33) |
| R04-R06 | 0000 | All-zero colors for clearing LEDs |
E5 Instruction Parameter Changes (Waterfall Version):
| Phase | OP00 | OP01 | OP10 | OP11 | Effect |
|---|---|---|---|---|---|
| Sequential on | 01 | 01 | 00 | 01โ0C | Light 1โ12 LEDs |
| Sequential off | 01 | 01 | 00 | 0Bโ01 | Light 11โ1 LEDs (right side turns off sequentially) |
| Final clear | 04 | 01 | 00 | 0C | All off |
Click to expand/collapse Register-based Delay Waterfall Full Code
- Mnemonic Form
- Instruction Form
000 FZ 0020 0080 R20 = 0080 (Delay duration = 128ms, modifiable to adjust speed)
001 FZ 0001 3300 R01 = 3300 (Color R=33, high byte)
002 FZ 0002 3300 R02 = 3300 (Color G=33)
003 FZ 0003 3300 R03 = 3300 (Color B=33)
004 FZ 0004 0000 R04 = 0000 (Clear color R=00)
005 FZ 0005 0000 R05 = 0000 (Clear color G=00)
006 FZ 0006 0000 R06 = 0000 (Clear color B=00)
========== Sequential On (010-027): OP11 increments from 01 to 0C ==========
010 E5 0101 0001 LED0 White (OP11=01, only 1 LED)
011 YS 0020 FF00 Read delay from R20 (128ms)
012 E5 0101 0002 LED0-LED1 White (OP11=02, 2 LEDs)
013 YS 0020 FF00 Read delay from R20
014 E5 0101 0003 LED0-LED2 White (OP11=03, 3 LEDs)
015 YS 0020 FF00 Delay
016 E5 0101 0004 LED0-LED3 White (OP11=04, 4 LEDs)
017 YS 0020 FF00 Delay
018 E5 0101 0005 LED0-LED4 White (OP11=05, 5 LEDs)
019 YS 0020 FF00 Delay
01A E5 0101 0006 LED0-LED5 White (OP11=06, 6 LEDs)
01B YS 0020 FF00 Delay
01C E5 0101 0007 LED0-LED6 White (OP11=07, 7 LEDs)
01D YS 0020 FF00 Delay
01E E5 0101 0008 LED0-LED7 White (OP11=08, 8 LEDs)
01F YS 0020 FF00 Delay
020 E5 0101 0009 LED0-LED8 White (OP11=09, 9 LEDs)
021 YS 0020 FF00 Delay
022 E5 0101 000A LED0-LED9 White (OP11=0A, 10 LEDs)
023 YS 0020 FF00 Delay
024 E5 0101 000B LED0-LED10 White (OP11=0B, 11 LEDs)
025 YS 0020 FF00 Delay
026 E5 0101 000C LED0-LED11 All lit (OP11=0C, 12 LEDs)
027 YS 0020 FF00 Delay
028 YS 0200 0000 Pause 512ms after all lit (uses immediate value for longer pause)
========== Sequential Off (029-03E): OP11 decrements from 0B to 01 ==========
029 E5 0101 000B LED0-LED10 (LED11 off, OP11=0B)
02A YS 0020 FF00 Read delay from R20
02B E5 0101 000A LED0-LED9 (LED10 off, OP11=0A)
02C YS 0020 FF00 Delay
02D E5 0101 0009 LED0-LED8
02E YS 0020 FF00 Delay
02F E5 0101 0008 LED0-LED7
030 YS 0020 FF00 Delay
031 E5 0101 0007 LED0-LED6
032 YS 0020 FF00 Delay
033 E5 0101 0006 LED0-LED5
034 YS 0020 FF00 Delay
035 E5 0101 0005 LED0-LED4
036 YS 0020 FF00 Delay
037 E5 0101 0004 LED0-LED3
038 YS 0020 FF00 Delay
039 E5 0101 0003 LED0-LED2
03A YS 0020 FF00 Delay
03B E5 0101 0002 LED0-LED1
03C YS 0020 FF00 Delay
03D E5 0101 0001 LED0
03E YS 0020 FF00 Delay
03F E5 0401 000C All off (R04-R06, start LED0, total 12)
040 YS 0020 FF00 Pause
041 ZY 0000 0010 Jump back to 010 loop
000 10 0020 0080
001 10 0001 3300
002 10 0002 3300
003 10 0003 3300
004 10 0004 0000
005 10 0005 0000
006 10 0006 0000
010 E5 0101 0001
011 02 0020 FF00
012 E5 0101 0002
013 02 0020 FF00
014 E5 0101 0003
015 02 0020 FF00
016 E5 0101 0004
017 02 0020 FF00
018 E5 0101 0005
019 02 0020 FF00
01A E5 0101 0006
01B 02 0020 FF00
01C E5 0101 0007
01D 02 0020 FF00
01E E5 0101 0008
01F 02 0020 FF00
020 E5 0101 0009
021 02 0020 FF00
022 E5 0101 000A
023 02 0020 FF00
024 E5 0101 000B
025 02 0020 FF00
026 E5 0101 000C
027 02 0020 FF00
028 02 0200 0000
029 E5 0101 000B
02A 02 0020 FF00
02B E5 0101 000A
02C 02 0020 FF00
02D E5 0101 0009
02E 02 0020 FF00
02F E5 0101 0008
030 02 0020 FF00
031 E5 0101 0007
032 02 0020 FF00
033 E5 0101 0006
034 02 0020 FF00
035 E5 0101 0005
036 02 0020 FF00
037 E5 0101 0004
038 02 0020 FF00
039 E5 0101 0003
03A 02 0020 FF00
03B E5 0101 0002
03C 02 0020 FF00
03D E5 0101 0001
03E 02 0020 FF00
03F E5 0401 000C
040 02 0020 FF00
041 0E 0000 0010
Key Optimization Notesโ
| Improvement | Previous Method | New Method | Comparison |
|---|---|---|---|
| Delay method | YS 0080 0000 (hardcoded 128ms) | YS 0020 FF00 (read from R20) | Modify R20 to adjust global speed, no need to modify each delay instruction line |
| Lighting method | E4 sets individual LED one by one | E5 0101 00NN batch setting | Reduced from 12 instructions to 1 instruction |
| Clear method | E4 clears one by one or E5 clears all at once | E5 achieves sequential clear by reducing count | Demonstrates flexibility of E5 OP11 parameter |
YS Register Mode Analysisโ
Using YS 0020 FF00 as example:
| Part | Value | Meaning |
|---|---|---|
| OP-0 | 0020 | Register number 20 (i.e. R20), reads duration value from it |
| OP-1 (high byte) | FF | Special marker: indicates register mode, not standard delay |
| OP-1 (low byte) | 00 | Unit: 00 = milliseconds |
Current R20 = 0080 = 128 (decimal), so each delay is 128ms. To speed up the waterfall, change FZ 0020 0080 on line 000 to FZ 0020 0040 (64ms) to make all delays uniformly faster.
Moon Phase Simulation (E5 Optimized Version: Brightness Fade + Batch Operation)โ
Key Improvements: Compared to the original moon phase simulation (DZ jump chain + E4 individual LED control with hardcoded colors), this optimized version features:
- E5 Batch Operation: One E5 instruction lights/extinguishes multiple LEDs at once, replacing the original 12 DZ jumps + 12 E4 instructions
- Register-stored Brightness: R01-R03 store current moonlight RGB values, dynamically updated through moon phases, enabling brightness gradient from new moon to full moon
- R20 Register Delay: Delay duration stored in R20, referenced via
YS 0020 FF00, allowing runtime adjustment of overall speed - Changing OP11 LED Count: Similar to the waterfall light idea, LED count changes via E5's OP11 parameter, replacing jump chains
Moonlight Colors (Cool White, Changes with Brightness):
| Phase | R | G | B | Register Value (High Byte) | Description |
|---|---|---|---|---|---|
| New Moon | 20 | 20 | 40 | R01=2000, R02=2000, R03=4000 | Faint moonlight |
| Waxing Crescent | 40 | 40 | 80 | R01=4000, R02=4000, R03=8000 | Brightening |
| First Quarter | 60 | 60 | C0 | R01=6000, R02=6000, R03=C000 | Medium brightness |
| Waxing Gibbous | A0 | A0 | E0 | R01=A000, R02=A000, R03=E000 | Brighter |
| Full Moon | E0 | E0 | FF | R01=E000, R02=E000, R03=FF00 | Brightest moonlight |
Register Planning:
| Register | Initial Value | Purpose |
|---|---|---|
| R20 | 0080 | Delay duration = 128ms (modifiable to adjust moon phase speed) |
| R01 | 2000 | Moonlight R value (updated through phases, uses high byte) |
| R02 | 2000 | Moonlight G value (updated through phases, uses high byte) |
| R03 | 4000 | Moonlight B value (updated through phases, uses high byte) |
| R04 | 0000 | Extinguish R = 00 |
| R05 | 0000 | Extinguish G = 00 |
| R06 | 0000 | Extinguish B = 00 |
E5 Instruction Parameter Changes (Moon Phase Version):
| Phase | OP00 | OP01 | OP10 | OP11 Change | Brightness Change | Effect |
|---|---|---|---|---|---|---|
| Waxing (Brightening) | 01 | 01 | 00 | 01โ0C | R/G/B values increase | 1 to 12 LEDs, brightness level increases every 2 steps |
| Waning (Dimming) | 01 | 01 | 00 | 0Bโ01 | R/G/B values decrease | 11 to 1 LEDs, brightness level decreases every 2 steps |
| Final Extinguish | 04 | 01 | 00 | 0C | All zero | All extinguished, returns to new moon state |
Click to expand/collapse E5 Optimized Moon Phase Simulation Full Code
- Mnemonic Form
- Instruction Form
000 FZ 0020 0080 R20 = 0080 (Delay = 128ms, modifiable for speed)
001 FZ 0001 2000 R01 = 2000 (Moonlight R initial = 20, high byte)
002 FZ 0002 2000 R02 = 2000 (Moonlight G initial = 20)
003 FZ 0003 4000 R03 = 4000 (Moonlight B initial = 40)
004 FZ 0004 0000 R04 = 0000 (Extinguish color R=00)
005 FZ 0005 0000 R05 = 0000 (Extinguish color G=00)
006 FZ 0006 0000 R06 = 0000 (Extinguish color B=00)
========== Waxing Phase (010-037): LED count 1โ12, brightness increasing ==========
010 E5 0101 0001 LED0 (1 LED) Faint moonlight (20,20,40)
011 YS 0020 FF00 Read delay from R20 (128ms)
012 E5 0101 0002 LED0-LED1 (2 LEDs)
013 YS 0020 FF00 Delay
014 FZ 0001 4000 Increase brightness: R = 40
015 FZ 0002 4000 Increase brightness: G = 40
016 FZ 0003 8000 Increase brightness: B = 80
017 E5 0101 0003 LED0-LED2 (3 LEDs) Dim moonlight (40,40,80)
018 YS 0020 FF00 Delay
019 E5 0101 0004 LED0-LED3 (4 LEDs)
01A YS 0020 FF00 Delay
01B FZ 0001 6000 Increase brightness: R = 60
01C FZ 0002 6000 Increase brightness: G = 60
01D FZ 0003 C000 Increase brightness: B = C0
01E E5 0101 0005 LED0-LED4 (5 LEDs) Medium brightness (60,60,C0)
01F YS 0020 FF00 Delay
020 E5 0101 0006 LED0-LED5 (6 LEDs)
021 YS 0020 FF00 Delay
022 FZ 0001 A000 Increase brightness: R = A0
023 FZ 0002 A000 Increase brightness: G = A0
024 FZ 0003 E000 Increase brightness: B = E0
025 E5 0101 0007 LED0-LED6 (7 LEDs) Bright moonlight (A0,A0,E0)
026 YS 0020 FF00 Delay
027 E5 0101 0008 LED0-LED7 (8 LEDs)
028 YS 0020 FF00 Delay
029 E5 0101 0009 LED0-LED8 (9 LEDs)
02A YS 0020 FF00 Delay
02B E5 0101 000A LED0-LED9 (10 LEDs)
02C YS 0020 FF00 Delay
02D FZ 0001 E000 Full moon brightness: R = E0
02E FZ 0002 E000 Full moon brightness: G = E0
02F FZ 0003 FF00 Full moon brightness: B = FF
030 E5 0101 000B LED0-LED10 (11 LEDs) Near full moon
031 YS 0020 FF00 Delay
032 E5 0101 000C LED0-LED11 (All 12 LEDs) **FULL MOON** (E0,E0,FF) โจ
033 YS 0200 FF00 Full moon long pause (use immediate value to make it stand out)
034 YS 0200 FF00 Another pause, enjoy the full moon
========== Waning Phase (035-056): LED count 11โ1, brightness decreasing ==========
035 FZ 0001 A000 Decrease brightness: R = A0
036 FZ 0002 A000 Decrease brightness: G = A0
037 FZ 0003 E000 Decrease brightness: B = E0
038 E5 0101 000B LED0-LED10 (11 LEDs) Waning begins
039 YS 0020 FF00 Delay
03A E5 0101 000A LED0-LED9 (10 LEDs)
03B YS 0020 FF00 Delay
03C E5 0101 0009 LED0-LED8 (9 LEDs)
03D YS 0020 FF00 Delay
03E E5 0101 0008 LED0-LED7 (8 LEDs)
03F YS 0020 FF00 Delay
040 FZ 0001 6000 Decrease brightness: R = 60
041 FZ 0002 6000 Decrease brightness: G = 60
042 FZ 0003 C000 Decrease brightness: B = C0
043 E5 0101 0007 LED0-LED6 (7 LEDs) Last quarter brightness
044 YS 0020 FF00 Delay
045 E5 0101 0006 LED0-LED5 (6 LEDs)
046 YS 0020 FF00 Delay
047 E5 0101 0005 LED0-LED4 (5 LEDs)
048 YS 0020 FF00 Delay
049 FZ 0001 4000 Decrease brightness: R = 40
04A FZ 0002 4000 Decrease brightness: G = 40
04B FZ 0003 8000 Decrease brightness: B = 80
04C E5 0101 0004 LED0-LED3 (4 LEDs) Waning crescent
04D YS 0020 FF00 Delay
04E E5 0101 0003 LED0-LED2 (3 LEDs)
04F YS 0020 FF00 Delay
050 FZ 0001 2000 Minimum brightness: R = 20
051 FZ 0002 2000 Minimum brightness: G = 20
052 FZ 0003 4000 Minimum brightness: B = 40
053 E5 0101 0002 LED0-LED1 (2 LEDs) Remaining moonlight
054 YS 0020 FF00 Delay
055 E5 0101 0001 LED0 (1 LED) Last trace of moonlight
056 YS 0020 FF00 Delay
057 E5 0401 000C All extinguished (R04-R06 all zero, LED0 start, 12 total) โ NEW MOON ๐
058 YS 0200 FF00 New moon pause
059 ZY 0000 0010 Jump back to 010, restart moon phase cycle
000 10 0020 0080
001 10 0001 2000
002 10 0002 2000
003 10 0003 4000
004 10 0004 0000
005 10 0005 0000
006 10 0006 0000
010 E5 0101 0001
011 02 0020 FF00
012 E5 0101 0002
013 02 0020 FF00
014 10 0001 4000
015 10 0002 4000
016 10 0003 8000
017 E5 0101 0003
018 02 0020 FF00
019 E5 0101 0004
01A 02 0020 FF00
01B 10 0001 6000
01C 10 0002 6000
01D 10 0003 C000
01E E5 0101 0005
01F 02 0020 FF00
020 E5 0101 0006
021 02 0020 FF00
022 10 0001 A000
023 10 0002 A000
024 10 0003 E000
025 E5 0101 0007
026 02 0020 FF00
027 E5 0101 0008
028 02 0020 FF00
029 E5 0101 0009
02A 02 0020 FF00
02B E5 0101 000A
02C 02 0020 FF00
02D 10 0001 E000
02E 10 0002 E000
02F 10 0003 FF00
030 E5 0101 000B
031 02 0200 FF00
032 E5 0101 000C
033 02 0200 FF00
034 02 0200 FF00
035 10 0001 A000
036 10 0002 A000
037 10 0003 E000
038 E5 0101 000B
039 02 0020 FF00
03A E5 0101 000A
03B 02 0020 FF00
03C E5 0101 0009
03D 02 0020 FF00
03E E5 0101 0008
03F 02 0020 FF00
040 10 0001 6000
041 10 0002 6000
042 10 0003 C000
043 E5 0101 0007
044 02 0020 FF00
045 E5 0101 0006
046 02 0020 FF00
047 E5 0101 0005
048 02 0020 FF00
049 10 0001 4000
04A 10 0002 4000
04B 10 0003 8000
04C E5 0101 0004
04D 02 0020 FF00
04E E5 0101 0003
04F 02 0020 FF00
050 10 0001 2000
051 10 0002 2000
052 10 0003 4000
053 E5 0101 0002
054 02 0020 FF00
055 E5 0101 0001
056 02 0020 FF00
057 E5 0401 000C
058 02 0200 FF00
059 0E 0000 0010
Key Optimization Comparison: Original vs E5 Optimizedโ
| Dimension | Original Moon Phase Simulation | E5 Optimized Moon Phase Simulation |
|---|---|---|
| Lighting Method | DZ jump chain + individual E4 per LED | E5 0101 00NN batch lighting (change OP11) |
| Lighting Instructions | ~12 DZ + 12 E4 = 24 instructions | ~24 E5 (but each controls N LEDs, cleaner) |
| Brightness Control | Hardcoded cool white (E0,E0,FF), no variation | Dynamic R01-R03 updates, 5-level brightness gradient โจ |
| Delay Duration | Hardcoded YS 0100 0000 | YS 0020 FF00 reads from R20, runtime adjustable |
| Direction Switching | DZ comparison + subroutine calls | Sequential execution (waxโwaneโcycle), no complex jumps |
Brightness Change Timelineโ
| Phase | Line Range | LED Count Change | RGB Brightness Change |
|---|---|---|---|
| Early Waxing | 010-013 | 1โ2 | (20,20,40) Faint |
| Mid Waxing | 014-021 | 3โ6 | (40,40,80) โ (60,60,C0) Brightening |
| Late Waxing | 022-02C | 7โ10 | (A0,A0,E0) Bright |
| Full Moon | 02D-034 | 11โ12 | (E0,E0,FF) Brightest โจ |
| Early Waning | 035-03F | 11โ8 | (A0,A0,E0) Dimming |
| Mid Waning | 040-048 | 7โ5 | (60,60,C0) Dimmer |
| Late Waning | 049-056 | 4โ1 | (40,40,80) โ (20,20,40) Dim |
| New Moon | 057-059 | All off | (00,00,00) ๐ |
Adjustable Brightness: How to Customize Moonlight Colorโ
To change moonlight color or brightness, simply modify the register initialization values:
| Desired Effect | Which Lines to Modify | Example Values |
|---|---|---|
| Cooler blue light | Line 003 R03 | FZ 0003 FF00 (B = FF) |
| Warmer yellow light | Lines 001-002 R01-R02 | FZ 0001 F000, FZ 0002 F000 |
| Overall dimmer | Lines 001-003 halve all | e.g., FZ 0001 1000, FZ 0002 1000, FZ 0003 2000 |
| Faster moon phase | Line 000 R20 | FZ 0020 0040 (Delay = 64ms) |
Community Library Smart Access Control System (100-Point Demo)โ
Hardware Requirementsโ
- 1 servo motor with pointer (WPWM instruction, channel 0)
- 1 full-color LED (CD / E4 instruction)
- Display device (digital output / serial โ shows current person count)
- Two infrared sensors (outside: Sensor A, inside: Sensor B)
- 1 staff emergency button
Core Opcodes: 10 (FZ) init ยท 11 register copy ยท 12 inc/dec ยท 13 register โ digital output (display) ยท WPWM (C8) servo control ยท CD (E4) LED color ยท 02 (YS) delay ยท 0E (ZY) jump ยท 09 conditional jump (equal) ยท 04 conditional jump (greater than) ยท 06 conditional jump (equal literal)
Scenario: Bidirectional Entry/Exit Detectionโ
Inside the library: max 10 people.
- Green LED when count < 10 โ space available โ
- Red LED when count == 10 โ no space ๐ซ
- Servo horizontal pointer โ door closed
- Servo vertical-down pointer โ door open
- Sensor A (outside) โ Sensor B (inside) โ person entering โ count++
- Sensor B (inside) โ Sensor A (outside) โ person exiting โ count--
- Staff button โ always opens door, does NOT change count (extended feature)
Sensor Input Values (R3F)โ
| R3F Value | Meaning |
|---|---|
0000 | No button / sensor pressed |
0001 | Sensor A (outside) triggered |
0002 | Sensor B (inside) triggered |
0004 | Staff emergency button |
Register Mapโ
| Register | Purpose | Initial Value |
|---|---|---|
| R09 | Current person count (0-10) | 0000 |
| R0A | Door state (0=closed, 1=open) | 0000 |
| R0B | Max capacity constant (10) | 000A |
| R0C | Temporary / comparison | 0000 |
| R0D | Previous R3F value (edge detection) | 0000 |
| R0E | Sequence memory (0=none, 1=A seen, 2=B seen) | 0000 |
| R0F | Sequence timeout counter | 0000 |
| R10 | Direction detected (0=none, 1=enter, 2=exit, 3=staff) | 0000 |
| R20 | Door-open delay counter | 00A0 |
| R21 | Sequence timeout threshold (8 loops) | 0008 |
| R22 | Constant 1 (for decrement compare) | 0001 |
Servo Positions (WPWM โ Channel 0)โ
| Position | WPWM Instruction | Meaning |
|---|---|---|
| Horizontal | WPWM 0000 0300 | Door closed |
| Vertical down | WPWM 0000 0C00 | Door open |
LED Color Referenceโ
| Color | CD Instruction (LED00) |
|---|---|
| Green (has space) | CD 0000 9900 |
| Red (full โ no space) | CD 0099 0000 |
| Off | CD 0000 0000 |
Complete Instruction Code (โ90 lines total)โ
================== Initialization (000-00E) ==================
000 10 0009 0000 R09 = 0 (count = 0, library is empty)
001 10 000A 0000 R0A = 0 (door = closed)
002 10 000B 000A R0B = 10 (max capacity, constant)
003 10 000D 0000 R0D = 0 (previous R3F = nothing)
004 10 000E 0000 R0E = 0 (no sequence detected yet)
005 10 000F 0000 R0F = 0 (sequence timeout counter)
006 10 0010 0000 R10 = 0 (no direction detected)
007 10 0020 00A0 R20 = A0 (door open duration)
008 10 0021 0008 R21 = 8 (reset sequence after 8 empty loops)
009 10 0022 0001 R22 = 1 (constant for comparisons)
00A C5 0001 0000 Enable PWM generator (required for servo)
00B WPWM 0000 0300 Servo channel 0 โ horizontal (door closed)
00C CD 0000 9900 LED00 = green (space available!)
00D 13 0009 0000 Digital output = R09 (display count "0")
================== Main Loop: Read Sensors (010-01F) ==================
010 11 0000 003F R00 = R3F (read current button/sensor state)
011 09 0000 0030 If R00==0: jump to 030 (no input, check timeout)
--- Edge detection: new press = R00!=0 AND R0D==0 ---
012 11 0001 000D R01 = R0D (previous state)
013 09 0000 0017 If R01==0: jump to 017 (new press detected)
014 ZY 0000 0020 Else: jump to count check (sensor still held โ skip)
--- New press detected โ route by sensor value ---
017 11 000D 0000 R0D = R00 (save current state for edge detection next loop)
018 09 0001 0040 If R00==1: jump to 040 (Sensor A โ outside)
019 09 0002 0050 If R00==2: jump to 050 (Sensor B โ inside)
01A 09 0004 0060 If R00==4: jump to 060 (Staff button โ emergency open)
01B ZY 0000 0020 Unknown input: jump to count check
================== Count Check & LED Update (020-02F) ==================
020 11 0000 0009 R00 = R09 (current count)
021 11 0001 000B R01 = R0B (max capacity = 10)
--- If count >= 10 โ RED LED (full) ---
022 04 0009 0028 If R00 > 9: jump to 028 (>=10 means full)
023 09 000A 0028 If R00==10: jump to 028 (exactly full)
--- Else โ GREEN LED (space available) ---
024 CD 0000 9900 LED00 = green โ
025 ZY 0000 002A Jump to display
--- Full capacity: turn LED RED ---
028 CD 0099 0000 LED00 = red ๐ซ
029 ZY 0000 002A Jump to display
--- Display current count on digital output pins ---
02A 13 0009 0000 Output = R09 (display current count)
02B ZY 0000 0070 Jump to delay/return
================== No-Input Timeout Handling (030-03F) ==================
030 10 000D 0000 R0D = 0 (no input โ reset edge detection)
031 09 0000 0020 If R0E==0: jump to count check (no sequence to timeout)
032 12 000F 0001 R0F += 1 (increment timeout counter)
033 11 0000 000F R00 = R0F
034 04 0007 0020 If R0F > 7: jump to count check (within threshold)
035 10 000E 0000 R0E = 0 (timeout: reset sequence memory)
036 10 000F 0000 R0F = 0 (reset timeout counter)
037 ZY 0000 0020 Jump to count check
================== Sensor A (Outside) Processing (040-04F) ==================
040 11 0000 000E R00 = R0E (what was seen before?)
041 09 0002 0048 If R0E==2: jump to 048 (B then A = person EXITING!)
042 09 0001 0045 If R0E==1: jump to 045 (A already seen โ ignore)
043 10 000E 0001 R0E = 1 (first sensor: A was seen โ remember)
044 ZY 0000 0020 Jump to count check (wait for second sensor)
045 10 000F 0000 R0F = 0 (reset timeout: sensor still active)
046 ZY 0000 0020 Jump to count check
--- B then A sequence confirmed โ person EXITING through door ---
048 11 0000 0009 R00 = R09 (check current count)
049 09 0000 0020 If count==0: jump to count check (can't go below 0!)
04A 2B 0009 0001 R09 -= 1 (count = count - 1)
04B 10 0010 0002 R10 = 2 (direction = EXIT)
04C 10 000E 0000 R0E = 0 (reset sequence memory)
04D ZY 0000 0080 Jump to door action (open door)
================== Sensor B (Inside) Processing (050-05F) ==================
050 11 0000 000E R00 = R0E (what was seen before?)
051 09 0001 0058 If R0E==1: jump to 058 (A then B = person ENTERING!)
052 09 0002 0055 If R0E==2: jump to 055 (B already seen โ ignore)
053 10 000E 0002 R0E = 2 (first sensor: B was seen โ remember)
054 ZY 0000 0020 Jump to count check (wait for second sensor)
055 10 000F 0000 R0F = 0 (reset timeout: sensor still active)
056 ZY 0000 0020 Jump to count check
--- A then B sequence confirmed โ person ENTERING through door ---
058 11 0000 0009 R00 = R09 (check current count)
059 04 0009 0020 If count > 9: jump to count check (full! can't enter)
05A 12 0009 0001 R09 += 1 (count = count + 1)
05B 10 0010 0001 R10 = 1 (direction = ENTER)
05C 10 000E 0000 R0E = 0 (reset sequence memory)
05D ZY 0000 0080 Jump to door action (open door)
================== Staff Emergency Button (060-07F) ==================
060 10 0010 0003 R10 = 3 (staff action โ don't change count!)
061 ZY 0000 0080 Jump to door action (open door regardless)
================== Door Action: Open โ Delay โ Close (080-08F) ==================
080 WPWM 0000 0C00 Servo โ vertical down (DOOR OPEN โ)
081 10 000A 0001 R0A = 1 (door state = open)
082 02 0020 FF00 Delay (hold door open for entry/exit)
083 WPWM 0000 0300 Servo โ horizontal (DOOR CLOSED โ)
084 10 000A 0000 R0A = 0 (door state = closed)
085 10 0010 0000 R10 = 0 (clear direction)
086 ZY 0000 0020 Jump to count check & LED update
================== Small Delay & Loop Back (070) ==================
070 02 0001 0000 Short delay (debounce)
071 ZY 0000 0010 Loop back to main loop
How It Works: Step-by-Step Flowโ
START
โ
โผ
Initialize registers, servo closed (horizontal), LED green
โ
โผ
Main Loop โโโบ Read R3F (sensors/buttons)
โ โ
โ โโโบ R3F==0 โ no input โ check sequence timeout โ LED update
โ โ
โ โโโบ R3F==1 โ Sensor A (outside)
โ โ โโโบ R0E==2 โ B then A โ count-- โ OPEN DOOR
โ โ โโโบ else โ R0E=1 (remember A), continue
โ โ
โ โโโบ R3F==2 โ Sensor B (inside)
โ โ โโโบ R0E==1 โ A then B โ count++ (if <10) โ OPEN DOOR
โ โ โโโบ else โ R0E=2 (remember B), continue
โ โ
โ โโโบ R3F==4 โ Staff button โ OPEN DOOR (no count change)
โ
โผ
Update LED: green if count<10, red if count==10
โ
โผ
Display count on digital output pins
โ
โผ
Loop back โโโโโโโโโโโโโ
Test Scenarios (Expected Results)โ
| Initial Count | Action | Expected New Count | LED | Servo |
|---|---|---|---|---|
| 0 | Sensor A then B (enter) | 1 | Green | Open โ Close |
| 1 | Sensor A then B (enter) | 2 | Green | Open โ Close |
| 9 | Sensor A then B (enter) | 10 | Red | Open โ Close |
| 10 | Sensor A then B (enter) | 10 (unchanged โ full!) | Red | N/A (won't open) |
| 1 | Sensor B then A (exit) | 0 | Green | Open โ Close |
| 0 | Sensor B then A (exit) | 0 (unchanged โ can't go below 0) | Green | N/A |
| Any | Staff button (0x04) | Unchanged | Same | Open โ Close |
Key Algorithm Conceptsโ
1. Bidirectional Detection (The Core Innovation) Two sensors positioned on opposite sides of the door detect direction:
- Sensor A is mounted on the outside of the library
- Sensor B is mounted on the inside of the library
- The sequence in which sensors are triggered determines direction:
- A โ B = walking in (entering library)
- B โ A = walking out (leaving library)
- A sequence timeout (R0F counter) resets memory if a person doesn't complete the crossing
2. Edge Detection (Prevent Double-Counting) R0D stores the "previous R3F value." A sensor is only processed when:
- Current R3F != 0 AND previous R3F == 0
- This means we only react to the press edge, not the continuous hold
- Essential for preventing the same person from being counted multiple times
3. Boundary Enforcement
- Cannot enter when count == 10 (library is full)
- Cannot exit when count == 0 (library is empty โ safety check)
- Count register (R09) is protected by bounds check before increment/decrement
4. Staff Override (Extended Feature) The staff button at R3F==4 always opens the door without changing the count. This is essential for:
- Library staff entering/exiting without being counted as visitors
- Emergency situations where someone is stuck
- Maintenance access
Customization Tipsโ
| What to Change | Which Register/Line | Example |
|---|---|---|
| Library capacity | Line 002 (R0B) | 10 000B 0014 โ capacity = 20 |
| Door open duration | Line 007 (R20) | 10 0020 00FF โ longer open time |
| Sequence timeout | Line 008 (R21) | 10 0021 0004 โ faster reset (shorter person) |
| Servo positions | Lines 00B and 080/083 | WPWM 0000 0500 โ different angle |
| LED color | Lines 00C, 024, 028 | CD 0000 00FF โ blue LED |