From 4f98480aebf70c02b58ce7ab731845c4d9318569 Mon Sep 17 00:00:00 2001
From: Jeff Epler <jepler@gmail.com>
Date: Thu, 5 Sep 2024 19:54:52 -0500
Subject: [PATCH] Add irq prev/next

---
 adafruit_pioasm.py    | 32 +++++++++++++++++++++++---------
 tests/test_version.py |  8 +++++++-
 2 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/adafruit_pioasm.py b/adafruit_pioasm.py
index 8ec06d7..04fb93c 100644
--- a/adafruit_pioasm.py
+++ b/adafruit_pioasm.py
@@ -325,19 +325,33 @@ def int_in_range(arg, low, high, what, radix=0):
                 if len(instruction) > 3:
                     assembled[-1] |= MOV_OPS.index(instruction[-2]) << 3
             elif instruction[0] == "irq":
-                #                instr delay z c w index
+                #                instr delay z c w tp/idx
                 assembled.append(0b110_00000_0_0_0_00000)
-                if instruction[-1] == "rel":
-                    assembled[-1] |= 0x10  # Set the high bit of the irq value
+
+                irq_type = 0
+                print(f"check prev/next/rel {instruction=}")
+                if instruction[-1] == "prev":
+                    irq_type = 1
+                    require_version(1, "irq prev")
+                    instruction.pop()
+                elif instruction[-1] == "next":
+                    irq_type = 3
+                    require_version(1, "irq next")
+                    instruction.pop()
+                elif instruction[-1] == "rel":
+                    irq_type = 2
                     instruction.pop()
-                num = int(instruction[-1], 0)
-                if not 0 <= num <= 7:
-                    raise RuntimeError("Interrupt index out of range")
+
+                assembled[-1] |= irq_type << 3
+
+                num = int_in_range(instruction[-1], 0, 8, "irq index")
                 assembled[-1] |= num
-                if len(instruction) == 3:  # after rel has been removed
-                    if instruction[1] == "wait":
+                instruction.pop()
+
+                if len(instruction) > 1:  # after rel has been removed
+                    if instruction[-1] == "wait":
                         assembled[-1] |= 0x20
-                    elif instruction[1] == "clear":
+                    elif instruction[-1] == "clear":
                         assembled[-1] |= 0x40
                     # All other values are the default of set without waiting
             elif instruction[0] == "set":
diff --git a/tests/test_version.py b/tests/test_version.py
index 8f69f18..0c8daaf 100644
--- a/tests/test_version.py
+++ b/tests/test_version.py
@@ -6,7 +6,7 @@
 Tests version dependent instructions
 """
 
-from pytest_helpers import assert_pio_kwargs, assert_assembly_fails
+from pytest_helpers import assert_pio_kwargs, assert_assembly_fails, assert_assembles_to
 
 
 def test_version() -> None:
@@ -107,3 +107,9 @@ def test_dot_set() -> None:
     assert_pio_kwargs(
         ".pio_version 1\n.set 16 right", pio_version=1, sideset_enable=0, set_count=16
     )
+
+
+def test_irq_v1() -> None:
+    assert_assembly_fails("irq 7 next")
+    assert_assembles_to(".pio_version 1\nirq 5 next", [0b110_00000_0_0_0_11_101])
+    assert_assembles_to(".pio_version 1\nirq wait 1 prev", [0b110_00000_0_0_1_01_001])