diff --git a/Makefile b/Makefile
index bec1b56..9516044 100644
--- a/Makefile
+++ b/Makefile
@@ -210,3 +210,19 @@ init-$($(module)_NAME):
update-$($(module)_NAME):
git subtree pull -P $($(module)_NAME) --squash $($(module)_REPO) $($(module)_BRANCH)
.endfor
+
+# Making diagrams, imported from fbsdembdev
+# =========================================
+# https://github.com/ironcamel/Graph-Easy
+
+.SUFFIXES: .getxt .diag .html
+
+.getxt.diag: box.sh
+ graph-easy < $< | sh $(.CURDIR)/box.sh > $@
+
+.diag.html:
+ (cat $<; echo; echo '') > $@
+
+DIAG?=diag
+test-diag:
+ ls $(.CURDIR)/box.sh $(.CURDIR)/$(DIAG).getxt $(.CURDIR)/Makefile | entr sh -c 'cd $(.CURDIR) && $(MAKE) $(.MAKEFLAGS) $(DIAG).diag && cat $(MAKEOBJDIR)/$(DIAG).diag'
diff --git a/arch.getxt b/arch.getxt
new file mode 100644
index 0000000..c5f3c01
--- /dev/null
+++ b/arch.getxt
@@ -0,0 +1,3 @@
+[ lora.py ] -- { label: multicast } [ loraserv.py ]
+[ loraserv.py ] -- { label: "USB VCP" } [ lora.gw.elf\nmain.c ]
+[ lora.gw.elf\nmain.c ] -- { label: LoRa } [ lora.irr.elf\nirr_main.c ]
diff --git a/box.sh b/box.sh
new file mode 100644
index 0000000..5fbf41b
--- /dev/null
+++ b/box.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+fname=$(mktemp foobar.XXXXX)
+cat > "$fname"
+awk '
+maxline == 1 {
+ if (maxlength < length)
+ maxlength = length
+}
+
+function printtop () {
+ blank = sprintf("%*s", maxlength + 4, "")
+ gsub(" ", "*", blank)
+ printf("%s\n", blank)
+}
+
+function printline(a)
+{
+ printf("* %s%*s *\n", a, maxlength - length(a), "")
+}
+
+# return the string a, with the character at pos, replaced with chr
+function replace(a, pos, chr)
+{
+ return substr(a, 1, pos - 1) chr substr(a, pos + 1)
+}
+
+output == 1 && FNR == 1 {
+ printtop()
+ printf("* %*s *\n", maxlength, "")
+
+ prevline = $0
+ next
+}
+
+output == 1 {
+ # fix up horizontal issues
+ gsub("\\|-", "+-", prevline)
+ gsub("\\| -", "+--", prevline)
+ gsub("-\\|", "-+", prevline)
+ gsub("- \\|", "--+", prevline)
+
+ # Fix up vertical issues
+
+ # first fix edges from below
+ r = split($0, a, "|")
+ pos = 0
+ for (i = 2; i <= r; i++) {
+ pos += length(a[i - 1]) + 1
+ if (substr(prevline, pos, 1) == "-")
+ prevline = replace(prevline, pos, "+")
+ }
+
+ # fix edges from above
+ r = split(prevline, a, "|")
+ pos = 0
+ for (i = 2; i <= r; i++) {
+ pos += length(a[i - 1]) + 1
+ if (substr($0, pos, 1) == "-")
+ $0 = replace($0, pos, "+")
+ }
+
+ printline(prevline)
+
+ prevline = $0
+}
+
+END {
+ printline(prevline)
+ printf("* %*s *\n", maxlength, "")
+ printtop()
+}
+' maxline=1 "$fname" maxline=0 output=1 "$fname"
+
+rm "$fname"
diff --git a/conns.getxt b/conns.getxt
new file mode 100644
index 0000000..2ac00e1
--- /dev/null
+++ b/conns.getxt
@@ -0,0 +1,6 @@
+[ 24V AC ] -- { label: "~/~" } [ AC-DC PS 5V ]
+[ AC-DC PS 5V ] -- { label: GND } [ Relay ]
+[ AC-DC PS 5V ] -- { label: "+5V -> JD-VCC" } [ Relay ]
+[ AC-DC PS 5V ] -- { label: GND } [ Node151 ]
+[ AC-DC PS 5V ] -- { label: "+5V -> VUSB" } [ Node151 ]
+[ Node151 ] -- { label: GPIO } [ Relay ]