<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>tpolecat industries –</title><link>https://tpolecat.github.io/www/blog/</link><description>Recent content on tpolecat industries</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 23 Sep 2026 10:38:15 -0500</lastBuildDate><atom:link href="https://tpolecat.github.io/www/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>Testing Servos with a Function Generator</title><link>https://tpolecat.github.io/www/blog/testing-servos/</link><pubDate>Wed, 23 Sep 2026 10:38:15 -0500</pubDate><guid>https://tpolecat.github.io/www/blog/testing-servos/</guid><description>
&lt;p&gt;Very quick post about testing servos without a servo tester, mostly for my own reference but here you go.&lt;/p&gt;
&lt;p&gt;&lt;video src="testing.mp4" controls&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;I occasionally build things with SG90 hobby servos and I like to hook them up and see them move without having to deal with a microcontroller. It&amp;rsquo;s easy to do with a function generator.&lt;/p&gt;
&lt;h3 data-hextra-search-id="control-signal"&gt;Control Signal&lt;span class="hx:absolute hx:-mt-20" id="control-signal"&gt;&lt;/span&gt;
&lt;a href="#control-signal" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;SG90 servos (and maybe others, I don&amp;rsquo;t know) are powered by 5V and have a third wire (orange), which is the control signal.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The control signal is a stream of &lt;strong&gt;20ms pulses&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The length of these pulses determines servo demand.&lt;/li&gt;
&lt;li&gt;Pulses vary between &lt;strong&gt;1ms&lt;/strong&gt; and &lt;strong&gt;2ms&lt;/strong&gt; in width, controlling 180° of movement.&lt;/li&gt;
&lt;li&gt;Behavior outside these ranges is usually undefined, but most servos can go a few tens of degrees past the limits.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-hextra-search-id="function-generator-setup"&gt;Function Generator Setup&lt;span class="hx:absolute hx:-mt-20" id="function-generator-setup"&gt;&lt;/span&gt;
&lt;a href="#function-generator-setup" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Set up the function generator as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Amplitide of &lt;strong&gt;5V&lt;/strong&gt;, offset &lt;strong&gt;+2.5V&lt;/strong&gt; (i.e., swinging between 0V and +5V).&lt;/li&gt;
&lt;li&gt;One of:
&lt;ul&gt;
&lt;li&gt;pulse mode with a period of &lt;strong&gt;20ms&lt;/strong&gt; and width of &lt;strong&gt;1.5ms&lt;/strong&gt;; or&lt;/li&gt;
&lt;li&gt;square wave at &lt;strong&gt;50Hz&lt;/strong&gt; with duty cycle of &lt;strong&gt;7.5%&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Wire up power and ground (red and brown) to the servo, connect the control wire (orange) to the function generator&amp;rsquo;s output, and connect function generator ground to the other ground wires. I made a little board so I can just plug everything in.&lt;/p&gt;
&lt;p&gt;The servo should zero itself when you power up and start producing a signal. Adjust the pulse duration between 1ms and 2ms (or 5% and 10% duty cycle) to test range of movement.&lt;/p&gt;</description></item><item><title>GALs by Example, Part 3</title><link>https://tpolecat.github.io/www/blog/gals-by-example-3/</link><pubDate>Sat, 19 Sep 2026 09:28:53 -0500</pubDate><guid>https://tpolecat.github.io/www/blog/gals-by-example-3/</guid><description>
&lt;p&gt;In &lt;a
href="../gals-by-example-2/"&gt;part two&lt;/a&gt; we learned how to use tri-state outputs to control access to and from a shared data bus. In this post we will learn how to implement &lt;strong&gt;sequential logic&lt;/strong&gt; by using the GAL16V8 in &lt;strong&gt;registered&lt;/strong&gt; mode.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;img src="https://tpolecat.github.io/www/blog/gals-by-example-3/shrimp.png" title="Running out of ideas. Here&amp;#39;s some salt and pepper shrimp." alt="" loading="lazy" /&gt;
&lt;figcaption&gt;Running out of ideas. Here&amp;#39;s some salt and pepper shrimp.&lt;/figcaption&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;h3 data-hextra-search-id="gal16v8-in-registered-mode"&gt;GAL16V8 in Registered Mode&lt;span class="hx:absolute hx:-mt-20" id="gal16v8-in-registered-mode"&gt;&lt;/span&gt;
&lt;a href="#gal16v8-in-registered-mode" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In registered mode we again have 16 inputs and 8 outputs, but the outputs can now be &lt;strong&gt;registered&lt;/strong&gt;, meaning they do not output their values immediately, but rather latch these values on the rising edge of the &lt;strong&gt;clock&lt;/strong&gt; (dedicated pin 1). All registered outputs share a single &lt;strong&gt;output-enable&lt;/strong&gt; (dedicated pin 11). Here is the pinout in registered mode.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;img src="https://tpolecat.github.io/www/blog/gals-by-example-3/registered.svg" title="GAL16V8 in Registered Mode" alt="" loading="lazy" /&gt;
&lt;figcaption&gt;GAL16V8 in Registered Mode&lt;/figcaption&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;At first glance it might appear that this mode is strictly better than complex mode, as tri-state outputs are still allowed in this mode (and none have the &amp;ldquo;no feedback&amp;rdquo; restriction). The catch is that while you can indeed have eight tri-state outputs in this mode, this would leave you with only eight inputs due to pins 1 and 11 being dedicated to &lt;code&gt;CLK&lt;/code&gt; and &lt;code&gt;/OE&lt;/code&gt;. In complex mode you would have ten inputs available. &lt;strong&gt;However&lt;/strong&gt; as far as I can tell, GALasm will only select registered mode if there is at least one registered output, so this question may be academic.&lt;/p&gt;
&lt;h3 data-hextra-search-id="a-parallel-load-shift-register"&gt;A Parallel-Load Shift Register&lt;span class="hx:absolute hx:-mt-20" id="a-parallel-load-shift-register"&gt;&lt;/span&gt;
&lt;a href="#a-parallel-load-shift-register" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A common task in electronics is turning serial data into a paralle data, which we do via a &lt;a
href="https://en.wikipedia.org/wiki/Shift_register"target="_blank" rel="noopener"&gt;shift register&lt;svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/&gt;
&lt;/svg&gt;&lt;/a&gt;. We will implement a 4-bit shift register with parallel load using a GAL16V8 in registered mode.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://tpolecat.github.io/www/blog/gals-by-example-3/shift.svg" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Bits shift in via &lt;code&gt;SDIN&lt;/code&gt; on the rising edge of &lt;code&gt;CLK&lt;/code&gt;, through bits &lt;code&gt;Q0&lt;/code&gt;, &lt;code&gt;Q1&lt;/code&gt;, &lt;code&gt;Q2&lt;/code&gt;, &lt;code&gt;Q3&lt;/code&gt;. &lt;code&gt;SDOUT&lt;/code&gt; is identical to &lt;code&gt;Q3&lt;/code&gt;. If &lt;code&gt;/LOAD&lt;/code&gt; is asserted then the values on &lt;code&gt;D[0:4]&lt;/code&gt; are copied to &lt;code&gt;Q[0:4]&lt;/code&gt; on the rising clock. If &lt;code&gt;/CLR&lt;/code&gt; is asserted then all bits are cleared on the rising clock.&lt;/p&gt;
&lt;p&gt;Here is the GALasm source in its entirety.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div class="hextra-code-filename not-prose" dir="auto"&gt;shift.pld&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;code&gt;GAL16V8
SHIFT
CLK /LOAD /CLR D3 D2 D1 D0 NC SDIN GND
/OE SDOUT NC Q3 Q2 Q1 Q0 NC NC VCC
Q0.R = /CLR &amp;amp; LOAD &amp;amp; D0
# /CLR &amp;amp; /LOAD &amp;amp; SDIN
Q1.R = /CLR &amp;amp; LOAD &amp;amp; D1
# /CLR &amp;amp; /LOAD &amp;amp; Q0
Q2.R = /CLR &amp;amp; LOAD &amp;amp; D2
# /CLR &amp;amp; /LOAD &amp;amp; Q1
Q3.R = /CLR &amp;amp; LOAD &amp;amp; D3
# /CLR &amp;amp; /LOAD &amp;amp; Q2
SDOUT.R = /CLR &amp;amp; LOAD &amp;amp; D3
# /CLR &amp;amp; /LOAD &amp;amp; Q2
DESCRIPTION
A 4-bit parallel load shift register.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-8"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We must specify &lt;code&gt;CLK&lt;/code&gt; at pin 1 and &lt;code&gt;/OE&lt;/code&gt; at pin 11. These are keyword labels like &lt;code&gt;VCC&lt;/code&gt; and &lt;code&gt;GND&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Registered outputs have the &lt;code&gt;.R&lt;/code&gt; suffix. The value is latched on the rising &lt;code&gt;CLK&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Much like tri-state outputs, we refer to the feedback from registered outputs &lt;em&gt;without&lt;/em&gt; a suffix. These refer to &lt;strong&gt;current&lt;/strong&gt; latched values, which we use to compute the &lt;strong&gt;next&lt;/strong&gt; latched values.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-hextra-search-id="testing"&gt;Testing&lt;span class="hx:absolute hx:-mt-20" id="testing"&gt;&lt;/span&gt;
&lt;a href="#testing" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Here is a test suite for the shift register. Note the use of the &lt;code&gt;C&lt;/code&gt; token for pin 1. This instructs minipro to issue a positive-going clock pulse before checking the output bits. Agan, refer to the &lt;a
href="../testing-gals/"&gt;post on testing GALs&lt;/a&gt; for more information.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div class="hextra-code-filename not-prose" dir="auto"&gt;buffer.xml&lt;/div&gt;&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;utf-8&amp;#34;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;logicic&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;database&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;LOGIC&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;custom&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;whatever-you-want&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;ic&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;shift&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;5&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;voltage=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;5V&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;pins=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;20&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C 01 1011 X X G 0 H X HLHH XXV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Load --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; X XX XXXX X X G 1 Z X ZZZZ XXV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Disable --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; X XX XXXX X X G 0 H X HLHH XXV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Enable --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C 11 XXXX X 0 G 0 L X LHHL XXV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Shift a 0 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C 11 XXXX X 1 G 0 H X HHLH XXV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Shift a 1 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C 11 XXXX X 1 G 0 H X HLHH XXV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Shift a 1 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X0 XXXX X X G 0 L X LLLL XXV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Clear --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/ic&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/custom&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/database&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/logicic&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-8"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-hextra-search-id="exercises"&gt;Exercises&lt;span class="hx:absolute hx:-mt-20" id="exercises"&gt;&lt;/span&gt;
&lt;a href="#exercises" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Program two shift registers and chain them together through &lt;code&gt;SDOUT&lt;/code&gt; and &lt;code&gt;SDIN&lt;/code&gt; to create an 8-bit shift register.&lt;/li&gt;
&lt;li&gt;Write a 4-bit counter.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>GALs by Example, Part 2</title><link>https://tpolecat.github.io/www/blog/gals-by-example-2/</link><pubDate>Fri, 18 Sep 2026 09:43:53 -0500</pubDate><guid>https://tpolecat.github.io/www/blog/gals-by-example-2/</guid><description>
&lt;p&gt;In &lt;a
href="../gals-by-example-1/"&gt;part one&lt;/a&gt; we learned about using the GAL16V8 in &lt;strong&gt;simple&lt;/strong&gt; mode, which allows only pure combinational logic. In this post we will learn how to use &lt;strong&gt;tri-state logic&lt;/strong&gt; in &lt;strong&gt;complex&lt;/strong&gt; mode.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;img src="https://tpolecat.github.io/www/blog/gals-by-example-2/cats.png" title="I couldn&amp;#39;t find a photo to illustrate tri-state logic but we do have three cats." alt="" loading="lazy" /&gt;
&lt;figcaption&gt;I couldn&amp;#39;t find a photo to illustrate tri-state logic but we do have three cats.&lt;/figcaption&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;In &lt;strong&gt;simple&lt;/strong&gt; mode, outputs could only be high or low. In this post we introduce &lt;strong&gt;complex&lt;/strong&gt; mode, which adds the possibility of outputs being &lt;strong&gt;individually disabled&lt;/strong&gt;. Disabled ouputs retain feedback and can be used as inputs, so they are effectively bidirectional.&lt;/p&gt;
&lt;h3 data-hextra-search-id="gal16v8-in-complex-mode"&gt;GAL16V8 in Complex Mode&lt;span class="hx:absolute hx:-mt-20" id="gal16v8-in-complex-mode"&gt;&lt;/span&gt;
&lt;a href="#gal16v8-in-complex-mode" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In complex mode we still have 16 input pins and 8 output pins, but they are arranged slightly differently. Here is the pinout when in complex mode.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;img src="https://tpolecat.github.io/www/blog/gals-by-example-2/pinout.svg" title="GAL16V8 in Complex Mode" alt="" loading="lazy" /&gt;
&lt;figcaption&gt;GAL16V8 in Complex Mode&lt;/figcaption&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Note that the pins 12 and 19 do not have feedback in this mode. This means they cannot be used in the right-hand side of an equation.&lt;/p&gt;
&lt;h3 data-hextra-search-id="a-bidirectional-buffer"&gt;A Bidirectional Buffer&lt;span class="hx:absolute hx:-mt-20" id="a-bidirectional-buffer"&gt;&lt;/span&gt;
&lt;a href="#a-bidirectional-buffer" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Many systems use a shared data bus, where components read and write to the same data lines. At any moment a component can be reading, writing, or ignoring the shared bus. A useful component to have in this situation is a bi-directional buffer with tri-state outputs, so that&amp;rsquo;s what we&amp;rsquo;re going to build.&lt;/p&gt;
&lt;p&gt;Our buffer will gate access to a three-bit bus. Data can flow from A to B, from B to A, or can be disconnected entirely. This is like a 3-bit version of a &lt;a
href="https://www.ti.com/lit/ds/symlink/sn74ls245.pdf"target="_blank" rel="noopener"&gt;74LS245&lt;svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/&gt;
&lt;/svg&gt;&lt;/a&gt; bus transceiver.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;img src="https://tpolecat.github.io/www/blog/gals-by-example-2/buffer.svg" title="A three-bit bidirectional buffer." alt="" loading="lazy" /&gt;
&lt;figcaption&gt;A three-bit bidirectional buffer.&lt;/figcaption&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Our choice of pins is more constrained this time. The inputs on the left can go anywhere, but we need feedback on our tri-state outputs so we can only use the six middle pins on the right side.&lt;/p&gt;
&lt;p&gt;Our GALasm prelude has the same format as in simple mode. Note that output &lt;code&gt;OE&lt;/code&gt; is active low. &lt;code&gt;DAB&lt;/code&gt; means &amp;ldquo;direction is from A to B&amp;rdquo;.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div class="hextra-code-filename not-prose" dir="auto"&gt;buffer.pld&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;code&gt;GAL16V8
BUFFER
/OE DAB NC NC NC NC NC NC NC GND
NC NC A0 A1 A2 B0 B1 B2 NC VCC&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-8"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The equations are a little different from what we saw in part one. Here are the equations for data flowing from A to B.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;; A -&amp;gt; B when enabled and DAB is asserted
B0.T = A0
B1.T = A1
B2.T = A2
B0.EN = OE &amp;amp; DAB
B1.EN = OE &amp;amp; DAB
B2.EN = OE &amp;amp; DAB&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We define a tri-state output by adding the &lt;code&gt;.T&lt;/code&gt; suffix. This means that &lt;code&gt;B0&lt;/code&gt; will have &lt;code&gt;A0&lt;/code&gt;&amp;rsquo;s value, but only when &lt;code&gt;B0&lt;/code&gt; is enabled.&lt;/li&gt;
&lt;li&gt;For each tri-state output we use a &lt;strong&gt;second&lt;/strong&gt; equation to specify when the output is enabled, via the &lt;code&gt;.EN&lt;/code&gt; suffix. In this case the B outputs are all enabled when output is enabled and the direction is from A to B.&lt;/li&gt;
&lt;li&gt;GALasm requires that each &lt;code&gt;.T&lt;/code&gt; equation appear before its associated &lt;code&gt;.E&lt;/code&gt; equation in the source file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The B to A flow is defined analogously, swapping &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; and enabling output when &lt;code&gt;DAB&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; asserted. Here is our final source file.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div class="hextra-code-filename not-prose" dir="auto"&gt;buffer.pld&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;code&gt;GAL16V8
BUFFER
/OE DAB NC NC NC NC NC NC NC GND
NC NC A0 A1 A2 B0 B1 B2 NC VCC
; A -&amp;gt; B when enabled and DAB is asserted
B0.T = A0
B1.T = A1
B2.T = A2
B0.EN = OE &amp;amp; DAB
B1.EN = OE &amp;amp; DAB
B2.EN = OE &amp;amp; DAB
; B -&amp;gt; A when enabled and DAB is disasserted
A0.T = B0
A1.T = B1
A2.T = B2
A0.EN = OE &amp;amp; /DAB
A1.EN = OE &amp;amp; /DAB
A2.EN = OE &amp;amp; /DAB
DESCRIPTION
A 3-bit bidirectional buffer.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-8"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-hextra-search-id="assembly-and-programming"&gt;Assembly and Programming&lt;span class="hx:absolute hx:-mt-20" id="assembly-and-programming"&gt;&lt;/span&gt;
&lt;a href="#assembly-and-programming" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;We assemble as we did in &lt;a
href="../gals-by-example-1/"&gt;part one&lt;/a&gt;. The &lt;code&gt;-v&lt;/code&gt; is optional but sometimes provides more output, which can be useful for debugging.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;$ galasm -v buffer.pld
GALasm 2.1, Portable GAL Assembler
Copyright (c) 1998-2003 Alessandro Zummo. All Rights Reserved
Original sources Copyright (c) 1991-96 Christian Habermann
Assembler Phase 1 for &amp;#34;buffer.pld&amp;#34;
Assembler Phase 2 for &amp;#34;buffer.pld&amp;#34;
Using complex mode because:
pin 13 (A0) is configured as tri-state output
pin 14 (A1) is configured as tri-state output
pin 15 (A2) is configured as tri-state output
pin 16 (B0) is configured as tri-state output
pin 17 (B1) is configured as tri-state output
pin 18 (B2) is configured as tri-state output
GAL16V8; Operation mode: complex; Security fuse off
Assembling successfully completed.
$ _&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that the operation mode has been inferred as &lt;strong&gt;complex&lt;/strong&gt; due to the presence of tri-state outputs. Programming is the same as in part one.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;$ minipro -p GAL16V8D -w buffer.jed
Found TL866II&amp;#43; 04.2.123 (0x27b)
Warning: Firmware is out of date.
Expected 04.2.132 (0x284)
Found 04.2.123 (0x27b)
Device code: 02106811
Serial code: N95SXK8LUBRHLHXHQG4Y
USB speed: 12Mbps (USB 1.1)
VPP=16V
Declared fuse checksum: 0x3A5E Calculated: 0x3A5E ... OK
Declared file checksum: 0x990C Calculated: 0x990C ... OK
JED file parsed OK
Erasing... 0.83Sec OK
Writing jedec file... 3.45Sec OK
Reading device... 0.09Sec OK
Verification OK
$ _&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-hextra-search-id="testing"&gt;Testing&lt;span class="hx:absolute hx:-mt-20" id="testing"&gt;&lt;/span&gt;
&lt;a href="#testing" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Our testing strategy is the same as in &lt;a
href="../gals-by-example-1/"&gt;part one&lt;/a&gt;, with one difference: when output is disabled we want to verify that the outputs are indeed high-impedance. For this we use the &lt;code&gt;Z&lt;/code&gt; output state.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div class="hextra-code-filename not-prose" dir="auto"&gt;buffer.xml&lt;/div&gt;&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;utf-8&amp;#34;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;logicic&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;database&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;LOGIC&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;custom&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;whatever-you-want&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;ic&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;buffer&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;5&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;voltage=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;5V&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;pins=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;20&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- A to B --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 01 XXXXXXXG XX 000 LLL XV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 01 XXXXXXXG XX 101 HLH XV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 01 XXXXXXXG XX 111 HHH XV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 11 XXXXXXXG XX 101 ZZZ XV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- B to A --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 00 XXXXXXXG XX LLL 000 XV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 00 XXXXXXXG XX HLH 101 XV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 00 XXXXXXXG XX HHH 111 XV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 10 XXXXXXXG XX ZZZ 101 XV &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/ic&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/custom&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/database&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/logicic&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-8"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that disabled outputs retain a weak pull-up, so pins marked &lt;code&gt;Z&lt;/code&gt; will measure high in isolation but will easily be swamped by active signals. Minipro detects this state by ensuring that the line can easily be pulled in either direction.&lt;/p&gt;
&lt;p&gt;We run our tests as before.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;$ minipro -T -p buffer --logicic buffer.xml
Using overridden database file buffer.xml
Found TL866II&amp;#43; 04.2.123 (0x27b)
Warning: Firmware is out of date.
Expected 04.2.132 (0x284)
Found 04.2.123 (0x27b)
Device code: 02106811
Serial code: N95SXK8LUBRHLHXHQG4Y
USB speed: 12Mbps (USB 1.1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
0000: 0 1 X X X X X X X G X X 0 0 0 L L L X V
0001: 0 1 X X X X X X X G X X 1 0 1 H L H X V
0002: 0 1 X X X X X X X G X X 1 1 1 H H H X V
0003: 1 1 X X X X X X X G X X 1 0 1 Z Z Z X V
0004: 0 0 X X X X X X X G X X L L L 0 0 0 X V
0005: 0 0 X X X X X X X G X X H L H 1 0 1 X V
0006: 0 0 X X X X X X X G X X H H H 1 1 1 X V
0007: 1 0 X X X X X X X G X X Z Z Z 1 0 1 X V
Logic test successful.
$ _ &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-hextra-search-id="exercises"&gt;Exercises&lt;span class="hx:absolute hx:-mt-20" id="exercises"&gt;&lt;/span&gt;
&lt;a href="#exercises" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Turn this into an &lt;strong&gt;inverting&lt;/strong&gt; buffer.&lt;/li&gt;
&lt;li&gt;Investigate the behavior of disabled outputs on a breadboard. Your &lt;a
href="https://www.aliexpress.us/item/3256809162514046.html"target="_blank" rel="noopener"&gt;99¢ Logic Probe&lt;svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/&gt;
&lt;/svg&gt;&lt;/a&gt; will show disabled lines as high. How strong is the pull-up?&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>GALs by Example, Part 1</title><link>https://tpolecat.github.io/www/blog/gals-by-example-1/</link><pubDate>Tue, 15 Sep 2026 13:45:18 -0500</pubDate><guid>https://tpolecat.github.io/www/blog/gals-by-example-1/</guid><description>
&lt;p&gt;GALs are simple programmable logic devices, (SPLDs) which are old technology but are &lt;a
href="https://www.digikey.com/en/products/filter/embedded/plds-programmable-logic-device/719?s=N4IgTCBcDaIOYEMA2IC6BfIA"target="_blank" rel="noopener"&gt;still available&lt;svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/&gt;
&lt;/svg&gt;&lt;/a&gt; and they remain popular among hobbysist as way to reduce the number of logic ICs in a project. Let&amp;rsquo;s learn how to use them!&lt;/p&gt;
&lt;p&gt;&lt;img src="https://tpolecat.github.io/www/blog/gals-by-example-1/gals.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Unlike their newer cousins the &lt;strong&gt;complex&lt;/strong&gt; programmable logic devices (CPLDs), GALs can be programmed with open-source software and inexpensive hardware. Truly modern programmable logic is dominated by field programmable gate arrays (FPGAs), but these are much more complex, have limited open-source support, and require auxiliary circuity to support their operation. GALs are very limited when compared to their modern counterparts, but they are much, much easier to use.&lt;/p&gt;
&lt;p&gt;Our basic workflow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Write a source file.&lt;/li&gt;
&lt;li&gt;Assemble it into a JEDEC file using GALasm.&lt;/li&gt;
&lt;li&gt;Write the JEDEC file to a GAL using minipro.&lt;/li&gt;
&lt;li&gt;Test the GAL, also using minipro.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-hextra-search-id="gal16v8-in-simple-mode"&gt;GAL16V8 in Simple Mode&lt;span class="hx:absolute hx:-mt-20" id="gal16v8-in-simple-mode"&gt;&lt;/span&gt;
&lt;a href="#gal16v8-in-simple-mode" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;To me the GAL16V8 is the Arduino Uno of the GAL world. It&amp;rsquo;s a 20-pin device with 16 pins that can be used as inputs and 8 that can be used as outputs (hence the name). We&amp;rsquo;re going to start with the GAL16V8 and use it in its simplest mode, conveniently called &amp;ldquo;simple mode&amp;rdquo;, which allows only for combinational logic. Here is the pinout when used in simple mode.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;img src="https://tpolecat.github.io/www/blog/gals-by-example-1/16V8simple.svg" title="GAL16V8 in Simple Mode" alt="" loading="lazy" /&gt;
&lt;figcaption&gt;GAL16V8 in Simple Mode&lt;/figcaption&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;h3 data-hextra-search-id="writing-a-logic-demo"&gt;Writing a Logic Demo&lt;span class="hx:absolute hx:-mt-20" id="writing-a-logic-demo"&gt;&lt;/span&gt;
&lt;a href="#writing-a-logic-demo" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;As far as I know, nobody manufactures a logic chip providing an AND gate, an OR gate, an XOR gate, and a NOT gate. So let&amp;rsquo;s make one using a GAL16V8 in simple mode.&lt;/p&gt;
&lt;p&gt;First let&amp;rsquo;s label our pins. We&amp;rsquo;ll need seven inputs and four outputs. I will use pins 1-7 for inputs (&lt;code&gt;A&lt;/code&gt;-&lt;code&gt;G&lt;/code&gt;) and 16-19 for outputs (&lt;code&gt;Q*&lt;/code&gt;), but this is arbitrary and you can use any valid pins you like.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;img src="https://tpolecat.github.io/www/blog/gals-by-example-1/logidemo.svg" title="Pin labels for our logic demo." alt="" loading="lazy" /&gt;
&lt;figcaption&gt;Pin labels for our logic demo.&lt;/figcaption&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start writing our GALasm source. At the top of the file we write a prelude that specifies our pin labels, as well as a few other things.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div class="hextra-code-filename not-prose" dir="auto"&gt;logidemo.pld&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;code&gt;GAL16V8
LOGIDEMO
A B C D E F G NC NC GND
NC NC NC NC NC QG QEF QCD QAB VCC&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-8"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Observe the following about the prelude:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first line identifies the GAL type.&lt;/li&gt;
&lt;li&gt;The second line is an arbitary signature of up to 8 ASCII characters.&lt;/li&gt;
&lt;li&gt;The next two lines label the pins in order from 1-10 and then 11-20.&lt;/li&gt;
&lt;li&gt;The special labels &lt;code&gt;GND&lt;/code&gt; and &lt;code&gt;VCC&lt;/code&gt; must be specified for power; and the special label &lt;code&gt;NC&lt;/code&gt; must be specified for unused pins.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After labeling the pins we provide &lt;strong&gt;equations&lt;/strong&gt; that compute the outputs from the inputs.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;; equations start here
QAB = A &amp;amp; B
QCD = C
# D
QEF = E &amp;amp; /F
# F &amp;amp; /E
QG = /G&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Equations must be in &lt;a
href="https://en.wikipedia.org/wiki/Disjunctive_normal_form"target="_blank" rel="noopener"&gt;Disjunctive Normal Form&lt;svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/&gt;
&lt;/svg&gt;&lt;/a&gt;, colloquially &amp;ldquo;sum of products&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;We express AND and OR with &lt;code&gt;&amp;amp;&lt;/code&gt; and &lt;code&gt;#&lt;/code&gt;, or with &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;+&lt;/code&gt;. Best to choose one style and stick with it.&lt;/li&gt;
&lt;li&gt;Inputs can be negated with &lt;code&gt;/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Equations can be broken across lines however you like, but it seems most common to have one product term per line.&lt;/li&gt;
&lt;li&gt;Comments start with a &lt;code&gt;;&lt;/code&gt; and go to the end of the line. They cannot appear in the prelude.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The epilogue of our source file &lt;em&gt;must&lt;/em&gt; contain the &lt;code&gt;DESCRIPTION&lt;/code&gt; keyword, so you might as well go ahead and write a description. Our final source file is as follows:&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div class="hextra-code-filename not-prose" dir="auto"&gt;logidemo.pld&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;code&gt;GAL16V8
LOGIDEMO
A B C D E F G NC NC GND
NC NC NC NC NC QG QEF QCD QAB VCC
; equations start here
QAB = A &amp;amp; B
QCD = C
# D
QEF = E &amp;amp; /F
# F &amp;amp; /E
QG = /G
DESCRIPTION
Example GAL definition with several combinational logic gates.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-8"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You may have noticed that we never declare that we want simple operating mode, nor do we specify which pins are inputs and which are outputs. Intead GALasm &lt;strong&gt;infers&lt;/strong&gt; these properties from the equations.&lt;/p&gt;
&lt;h3 data-hextra-search-id="assembly"&gt;Assembly&lt;span class="hx:absolute hx:-mt-20" id="assembly"&gt;&lt;/span&gt;
&lt;a href="#assembly" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Before we assemble our source we need to install &lt;a
href="https://github.com/daveho/GALasm"target="_blank" rel="noopener"&gt;GALasm&lt;svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/&gt;
&lt;/svg&gt;&lt;/a&gt;. Download the repo, go into &lt;code&gt;src&lt;/code&gt;, and &lt;code&gt;make&lt;/code&gt;. The output is a single binary &lt;code&gt;galasm&lt;/code&gt; that you can move wherever you want.&lt;/p&gt;
&lt;p&gt;And now, we assemble:&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;$ galasm -v logidemo.pld
GALasm 2.1, Portable GAL Assembler
Copyright (c) 1998-2003 Alessandro Zummo. All Rights Reserved
Original sources Copyright (c) 1991-96 Christian Habermann
Assembler Phase 1 for &amp;#34;logidemo.pld&amp;#34;
Assembler Phase 2 for &amp;#34;logidemo.pld&amp;#34;
Defaulting to simple mode
GAL16V8; Operation mode: simple; Security fuse off
Assembling successfully completed.
$ _&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If everything went well you will see something like the output above. Note that the next-to-last line identifies the operation mode as &lt;strong&gt;simple&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;There are four output files:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;File&lt;/th&gt;
&lt;th style="text-align: left"&gt;Descripion&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;logidemo.chp&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;An ASCII-art picture of the IC, with our pin labels.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;logidemo.pin&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;A text file with a table of pin types and labels.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;logidemo.fus&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Human-readable tables for the fuses that will be set in the GAL.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;logidemo.jed&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;JEDEC file that we can actually program onto the GAL.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If things did &lt;em&gt;not&lt;/em&gt; go well you may have been presented with an error message, and it might not make any sense. If the error is &lt;code&gt;Error: Not enough free memory!&lt;/code&gt; it can mean a lot of things, including file not found. You&amp;rsquo;ll have to mess around and figure out what&amp;rsquo;s going on.&lt;/p&gt;
&lt;h3 data-hextra-search-id="programming"&gt;Programming&lt;span class="hx:absolute hx:-mt-20" id="programming"&gt;&lt;/span&gt;
&lt;a href="#programming" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Now that we have our JEDEC file we can program the GAL with &lt;a
href="https://gitlab.com/DavidGriffith/minipro"target="_blank" rel="noopener"&gt;minipro&lt;svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/&gt;
&lt;/svg&gt;&lt;/a&gt;. See the repo&amp;rsquo;s README for installation instructions; it&amp;rsquo;s available on many package managers. You will also need a TL866 or &lt;a
href="https://www.amazon.com/s?k=T48&amp;#43;programmer"target="_blank" rel="noopener"&gt;T48&lt;svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/&gt;
&lt;/svg&gt;&lt;/a&gt; programmer, and it needs to be plugged into your computer.&lt;/p&gt;
&lt;p&gt;There are many variations of the GAL16V8, so check the list on minipro and see if yours shows up. Unless specified otherwise the package is DIP.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;$ minipro -L GAL16V8
Found TL866II&amp;#43; 04.2.123 (0x27b)
Warning: Firmware is out of date.
Expected 04.2.132 (0x284)
Found 04.2.123 (0x27b)
Device code: 02106811
Serial code: N95SXK8LUBRHLHXHQG4Y
USB speed: 12Mbps (USB 1.1)
GAL16V8
GAL16V8@SOIC20
GAL16V8A
GAL16V8A@SOIC20
GAL16V8B
GAL16V8B@SOIC20
GAL16V8C
GAL16V8C@SOIC20
GAL16V8D
GAL16V8D@SOIC20
$ _&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;GAL16V8D&lt;/code&gt; seems to be the common modern variant (sometimes there are other letters before the &lt;code&gt;D&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;To program, place your GAL in the programmer&amp;rsquo;s ZIF socket, aligning it according to the indication on the programmer. Then program, using your best guess for the part number:&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;$ minipro -p GAL16V8D -w logidemo.jed
Found TL866II&amp;#43; 04.2.123 (0x27b)
Warning: Firmware is out of date.
Expected 04.2.132 (0x284)
Found 04.2.123 (0x27b)
Device code: 02106811
Serial code: N95SXK8LUBRHLHXHQG4Y
USB speed: 12Mbps (USB 1.1)
VPP=16V
Declared fuse checksum: 0x24B7 Calculated: 0x24B7 ... OK
Declared file checksum: 0x6B98 Calculated: 0x6B98 ... OK
JED file parsed OK
Erasing... 0.83Sec OK
Writing jedec file... 3.45Sec OK
Reading device... 0.09Sec OK
Verification OK
$ _&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And that&amp;rsquo;s it. You can put the GAL on a breadboard and try it out, or keep reading and write a unit test. If programming fails, check the part number. If verification fails you may have a defective GAL. I just threw one in the trash for this reason.&lt;/p&gt;
&lt;h3 data-hextra-search-id="testing"&gt;Testing&lt;span class="hx:absolute hx:-mt-20" id="testing"&gt;&lt;/span&gt;
&lt;a href="#testing" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;We can write a minipro testcase with an XML file. Each &lt;code&gt;&amp;lt;vector&amp;gt;&lt;/code&gt; below is a single test, specifying pins from 1 to 20, where &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt; drives the pin and &lt;code&gt;H&lt;/code&gt; or &lt;code&gt;L&lt;/code&gt; are expected outputs. &lt;code&gt;X&lt;/code&gt; means &amp;ldquo;don&amp;rsquo;t care&amp;rdquo;, and &lt;code&gt;V&lt;/code&gt;/&lt;code&gt;G&lt;/code&gt; are for power. Whitespace is ignored so I grouped the pins in a way that made sense to me.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div class="hextra-code-filename not-prose" dir="auto"&gt;logidemo.xml&lt;/div&gt;&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;utf-8&amp;#34;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;logicic&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;database&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;LOGIC&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;custom&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;whatever-you-want&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;ic&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;logidemo&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;5&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;voltage=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;5V&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;pins=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;20&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- AND gate at pins 1-2, output on 19 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 00 XX XX X XXG XXXXX X X X L V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 01 XX XX X XXG XXXXX X X X L V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 10 XX XX X XXG XXXXX X X X L V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 11 XX XX X XXG XXXXX X X X H V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- OR gate at pins 3-4, output on 18 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; XX 00 XX X XXG XXXXX X X L X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; XX 01 XX X XXG XXXXX X X H X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; XX 10 XX X XXG XXXXX X X H X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; XX 11 XX X XXG XXXXX X X H X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- XOR gate at pins 5-6, output on 17 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; XX XX 00 X XXG XXXXX X L X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; XX XX 01 X XXG XXXXX X H X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; XX XX 10 X XXG XXXXX X H X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; XX XX 11 X XXG XXXXX X L X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- NOT gate at pin 7, output on 16 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; XX XX XX 0 XXG XXXXX H X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; XX XX XX 1 XXG XXXXX L X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/ic&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/custom&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/database&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/logicic&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-8"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Running the test with &lt;code&gt;minipro&lt;/code&gt; shows no errors!&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;$ minipro -T -p logidemo --logicic logidemo.xml
Using overridden database file logidemo.xml
Found TL866II&amp;#43; 04.2.123 (0x27b)
Warning: Firmware is out of date.
Expected 04.2.132 (0x284)
Found 04.2.123 (0x27b)
Device code: 02106811
Serial code: N95SXK8LUBRHLHXHQG4Y
USB speed: 12Mbps (USB 1.1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
0000: 0 0 X X X X X X X G X X X X X X X X L V
0001: 0 1 X X X X X X X G X X X X X X X X L V
0002: 1 0 X X X X X X X G X X X X X X X X L V
0003: 1 1 X X X X X X X G X X X X X X X X H V
0004: X X 0 0 X X X X X G X X X X X X X L X V
0005: X X 0 1 X X X X X G X X X X X X X H X V
0006: X X 1 0 X X X X X G X X X X X X X H X V
0007: X X 1 1 X X X X X G X X X X X X X H X V
0008: X X X X 0 0 X X X G X X X X X X L X X V
0009: X X X X 0 1 X X X G X X X X X X H X X V
0010: X X X X 1 0 X X X G X X X X X X H X X V
0011: X X X X 1 1 X X X G X X X X X X L X X V
0012: X X X X X X 0 X X G X X X X X H X X X V
0013: X X X X X X 1 X X G X X X X X L X X X V
Logic test successful.
$ _&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;See this &lt;a
href="../testing-gals/"&gt;post about testing GALs&lt;/a&gt; for much more detail.&lt;/p&gt;
&lt;h3 data-hextra-search-id="other-features"&gt;Other Features&lt;span class="hx:absolute hx:-mt-20" id="other-features"&gt;&lt;/span&gt;
&lt;a href="#other-features" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Here are some other features that can be useful in simple mode. We will revisit these in later posts.&lt;/p&gt;
&lt;h4 data-hextra-search-id="feedback"&gt;Feedback&lt;span class="hx:absolute hx:-mt-20" id="feedback"&gt;&lt;/span&gt;
&lt;a href="#feedback" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Output pins provide &lt;strong&gt;feedback&lt;/strong&gt;, which allows equations to mention outputs in their right-hand sides. For example, we could write equations that computes &lt;code&gt;AND&lt;/code&gt; and &lt;code&gt;OR&lt;/code&gt; and re-use these results to compute &lt;code&gt;XOR&lt;/code&gt;.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;QAND = A &amp;amp; B
QOR = A # B
QXOR = OR &amp;amp; /AND ; this equation mentions *outputs*&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Feedback isn&amp;rsquo;t strictly necessary in simple mode, but it can save some repetition. When we get to &lt;strong&gt;registered&lt;/strong&gt; mode we will use feedback to see prior values stored on the previous clock cycle, allowing for sequential logic.&lt;/p&gt;
&lt;h4 data-hextra-search-id="active-low-pins"&gt;Active-Low Pins&lt;span class="hx:absolute hx:-mt-20" id="active-low-pins"&gt;&lt;/span&gt;
&lt;a href="#active-low-pins" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;When we write equations we should really think of &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;/A&lt;/code&gt; as meaning pin A is logically &lt;strong&gt;asserted&lt;/strong&gt; or &lt;strong&gt;non-asserted&lt;/strong&gt;, as opposed to thinking about physical voltage. Pins are active-high by default, but we can mark pins as &lt;strong&gt;active low&lt;/strong&gt; when we declare pin labels by preceding the label with a &lt;code&gt;/&lt;/code&gt;. For instance, making this single change to our example above effectively changes the first gate from AND to NAND.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;A B C D E F G NC NC GND
NC NC NC NC NC QG QEF QCD /QAB VCC&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We still refer to the pin as &lt;code&gt;QAB&lt;/code&gt; in the rest of our code and it&amp;rsquo;s still asserted when &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; are both asserted, but assertion of &lt;code&gt;QAB&lt;/code&gt; now means that the output will now be low rather than high. This also works for input pins; signals like &amp;ldquo;enable&amp;rdquo; are often active low.&lt;/p&gt;
&lt;p&gt;The takeaway is that the choice of active-high or active-low is &lt;strong&gt;orthogogonal&lt;/strong&gt; to your equations, which should be written in terms of assertion rather than physical logic level.&lt;/p&gt;
&lt;h4 data-hextra-search-id="pullups"&gt;Pullups&lt;span class="hx:absolute hx:-mt-20" id="pullups"&gt;&lt;/span&gt;
&lt;a href="#pullups" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;The GAL16V8 provides active pullups for inputs and unassigned outputs, which allows (for example) an input to be connected to ground through a switch without an additional pull-up, becauese the floating input will be pulled to a logic high.&lt;/p&gt;
&lt;p&gt;Pull-downs in the TL866 programmer seem to make it impossible to create truly floating inputs for tests; inputs marked with an &lt;code&gt;X&lt;/code&gt; seem to have indeterminate logic values. So you need to pop the GAL into a breadboard to test this behavior. An &lt;a
href="https://www.aliexpress.us/item/3256809162514046.html"target="_blank" rel="noopener"&gt;99¢ Logic Probe&lt;svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/&gt;
&lt;/svg&gt;&lt;/a&gt; is great for this kind of thing.&lt;/p&gt;
&lt;h3 data-hextra-search-id="exercises"&gt;Exercises&lt;span class="hx:absolute hx:-mt-20" id="exercises"&gt;&lt;/span&gt;
&lt;a href="#exercises" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I encourge you to do some of these exercises (or make up some of your own) before moving on to the next post.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Change &lt;code&gt;QCD&lt;/code&gt; to compute NOR and verify that the test fails. Fix the test.&lt;/li&gt;
&lt;li&gt;Play around with active-low inputs and outputs until you&amp;rsquo;re confident you understand how they work.&lt;/li&gt;
&lt;li&gt;Use a breadboard to check the behavior of floating inputs and unused outputs.&lt;/li&gt;
&lt;li&gt;Modify equations to ouput &lt;code&gt;AND&lt;/code&gt;, &lt;code&gt;OR&lt;/code&gt;, and &lt;code&gt;XOR&lt;/code&gt; for a &lt;em&gt;single&lt;/em&gt; pair of inputs. Add some other relations like &lt;code&gt;NAND&lt;/code&gt;. Feedback can be useful here.&lt;/li&gt;
&lt;li&gt;Build a half adder, taking inputs &lt;code&gt;A0&lt;/code&gt; and &lt;code&gt;A1&lt;/code&gt; and producing output &lt;code&gt;S&lt;/code&gt; for the sum and &lt;code&gt;CO&lt;/code&gt; for the carry out.&lt;/li&gt;
&lt;li&gt;Build a full adder, taking inputs &lt;code&gt;A0&lt;/code&gt; and &lt;code&gt;A1&lt;/code&gt; as well as &lt;code&gt;CI&lt;/code&gt; for carry in, producing output &lt;code&gt;S0&lt;/code&gt; and &lt;code&gt;S1&lt;/code&gt; for the sum and &lt;code&gt;CO&lt;/code&gt; for final carry out.&lt;/li&gt;
&lt;li&gt;Build a 7-segment LED decoder, taking inputs &lt;code&gt;D0&lt;/code&gt; through &lt;code&gt;D3&lt;/code&gt; and producing outputs &lt;code&gt;A&lt;/code&gt; through &lt;code&gt;G&lt;/code&gt; for the LED segments such that the hexadecimal value of the 4-bit input is displayed as &lt;code&gt;0&lt;/code&gt;..&lt;code&gt;F&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>I Fixed the Air Conditioner</title><link>https://tpolecat.github.io/www/blog/fixing-ac/</link><pubDate>Sun, 13 Sep 2026 15:23:37 -0500</pubDate><guid>https://tpolecat.github.io/www/blog/fixing-ac/</guid><description>
&lt;p&gt;&lt;img src="https://tpolecat.github.io/www/blog/fixing-ac/lowes.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;The AC went out last night and it was 82° inside this morning. All the HVAC contractors are super busy in Texas in the summer, and the best we could get was an appointment in three days. Not good enough. So I decided to give it a look myself.&lt;/p&gt;
&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-red-200 hx:bg-red-100 hx:text-red-900 hx:dark:border-red-200/30 hx:dark:bg-red-900/30 hx:dark:text-red-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;I am not an electrician, I am a hobbyist. I have some experience with mains power but I am absolutely
not qualified to tell you how to do this kind of thing. This is just a report about what I did and how it
worked out.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It turns out the most common failure, a dead run capacitor, is easy to diagnose and easy to fix. My symptoms were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The outside fan was spinning (this was unusual) but the compressor wasn&amp;rsquo;t running.&lt;/li&gt;
&lt;li&gt;From time to time it would buzz for a couple seconds.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The problem is that without some capacitance to provide a phase shift in the current, the compressor motor can&amp;rsquo;t start or keep running. The fan motor seemed to get by ok for some reason. In any case, the big capacitor was rusty and bulging so I suspected that was the problem. Here&amp;rsquo;s what I did to diagnose.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Turned the air conditioning off at the thermostat.&lt;/li&gt;
&lt;li&gt;Pulled out the cutoff breaker in the utility box for the AC unit.&lt;/li&gt;
&lt;li&gt;Removed the service panel.&lt;/li&gt;
&lt;li&gt;Checked AC voltage inside to be sure it was really disconnected.&lt;/li&gt;
&lt;li&gt;Checked DC voltage across the capacitor, between the compressor terminal (3 prongs) and common (4 prongs), and between the fan terminal (2 prongs) and common. Normally these will be zero because the capacitor will drain through the motor coils, but if a coil is broken then the cap can contain a deadly amount of energy that needs to be discharged Watching the number go down while I hold multimeter probes across the terminals is the way I like to do this, rather than making a huge bang with a screwdriver. In my case all were zero.&lt;/li&gt;
&lt;li&gt;Checked resistance across the same pairs of terminals. It was a few ohms for the compressor coil and a few tens of ohms for the fan coil, which seemed reasonable. They were not shorted, which made me fairly confident the motors were ok.&lt;/li&gt;
&lt;li&gt;Checked capacitance across the same pairs of terminals. Nothing. Multimeter didn&amp;rsquo;t recognize that anything was connected. I took a photo of the wiring and then disconnected the cap and checked it on the LCR meter and it was just a few picofarads on both sides. Completely dead.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now confident in my belief that the cap was bad I entered Lowe&amp;rsquo;s with a purposeful stride and walked to the capacitor section. However there was no such section so I strode back out and drove down the street to Home Depot, which did have a capacitor in the neighborhood of what I needed. Mine was a 45/5 and those were sold out, so I got a 50/5. A little extra can&amp;rsquo;t hurt. I assume.&lt;/p&gt;
&lt;p&gt;Anyway, back home, plugged everything in and it worked. House is back down to 75° and everyone&amp;rsquo;s mood is much improved. Total cost was $25 and I am now a local hero.&lt;/p&gt;</description></item><item><title>Testing GALs with Minipro</title><link>https://tpolecat.github.io/www/blog/testing-gals/</link><pubDate>Thu, 10 Sep 2026 10:37:58 -0500</pubDate><guid>https://tpolecat.github.io/www/blog/testing-gals/</guid><description>
&lt;p&gt;&lt;img src="https://tpolecat.github.io/www/blog/testing-gals/tl866.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;I have used GALs a lot and always ended up testing them on breadboards with jumper wires, which doesn&amp;rsquo;t inspire a lot of confidence. But I recently discovered that I can write comprehensive test suites and run them with &lt;a
href="https://gitlab.com/DavidGriffith/minipro"target="_blank" rel="noopener"&gt;minipro&lt;svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/&gt;
&lt;/svg&gt;&lt;/a&gt;. Here&amp;rsquo;s how it works.&lt;/p&gt;
&lt;h3 data-hextra-search-id="testing-common-logic-ics"&gt;Testing Common Logic ICs&lt;span class="hx:absolute hx:-mt-20" id="testing-common-logic-ics"&gt;&lt;/span&gt;
&lt;a href="#testing-common-logic-ics" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Minipro has a test feature for common logic chips, which you invoke with &lt;code&gt;-T&lt;/code&gt;. For example, if I put a 74LS14 hex inverter into my programmer I can test it by specifying part &lt;code&gt;7414&lt;/code&gt;.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;$ minipro -p 7414 -T
Found TL866II&amp;#43; 04.2.123 (0x27b)
Device code: 02106811
Serial code: N95SXK8LUBRHLHXHQG4Y
USB speed: 12Mbps (USB 1.1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
0000: 0 H 0 H 0 H G H 0 H 0 H 0 V
0001: 1 L 1 L 1 L G L 1 L 1 L 1 V
Logic test successful.
$ &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This test has two cases, each of which is specified as a single line of tokens, one per pin:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; specify &lt;strong&gt;input&lt;/strong&gt; lines that will be driven low or high.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;V&lt;/code&gt; and &lt;code&gt;G&lt;/code&gt; specify the VCC and ground pins.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;H&lt;/code&gt; and &lt;code&gt;L&lt;/code&gt; specify expected &lt;strong&gt;outputs&lt;/strong&gt; that will be checked.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Test cases are run in order from top to bottom (several times around to catch flaky tests).&lt;/p&gt;
&lt;p&gt;This test and many others are defined in the &lt;code&gt;logicic.xml&lt;/code&gt; file that minipro installs. On my machine it&amp;rsquo;s located in &lt;code&gt;/opt/homebrew/share/minipro/&lt;/code&gt;. Here&amp;rsquo;s the specification for &lt;code&gt;7414&lt;/code&gt; and a bunch of other inverters with the same pinout. Note that the &lt;code&gt;&amp;lt;vector&amp;gt;&lt;/code&gt; elements exactly match the test output above.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;ic&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;40106,7416,7414,7406,7405,7404,4584,4069&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;5&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;voltage=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;5V&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;pins=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;14&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;00&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 0 H 0 H 0 H G H 0 H 0 H 0 V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;01&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 1 L 1 L 1 L G L 1 L 1 L 1 V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/ic&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So the game here is to write our own test definitions.&lt;/p&gt;
&lt;h3 data-hextra-search-id="testing-gals"&gt;Testing GALs&lt;span class="hx:absolute hx:-mt-20" id="testing-gals"&gt;&lt;/span&gt;
&lt;a href="#testing-gals" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Here is a &lt;a
href="https://github.com/daveho/GALasm"target="_blank" rel="noopener"&gt;GALasm&lt;svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"&gt;
&lt;path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/&gt;
&lt;/svg&gt;&lt;/a&gt; definition for a GAL16V8 that maintains five flip-flops that are set and reset by various input signals.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;GAL16V8
GPIODEC
Clock NC ST3 ST2 ST1 RODT SODT RRST SRST GND
/OE /ODT /T3 /T2 /T1 /RST NC NC NC VCC
RST.R = SRST
&amp;#43; RST * /RRST
ODT.R = /SRST * /RST * SODT
&amp;#43; /SRST * /RST * ODT * /RODT
T1.R = /SRST * /RST * ST1
&amp;#43; /SRST * /RST * T1
T2.R = /SRST * /RST * ST2
&amp;#43; /SRST * /RST * T2
T3.R = /SRST * /RST * ST3
&amp;#43; /SRST * /RST * T3
DESCRIPTION
This decodes the GPIO signals we care about.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And here is a custom test database with a specification for our GAL. We place this test in a new file of our choosing (we don&amp;rsquo;t need to modify the shared file).&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div class="hextra-code-filename not-prose" dir="auto"&gt;test.xml&lt;/div&gt;&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;utf-8&amp;#34;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;logicic&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;database&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;LOGIC&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;custom&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;tpolecat industries&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;ic&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;gp1&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;5&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;voltage=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;5V&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;pins=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;20&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- Clock NC ST3 ST2 ST1 RODT SODT RRST SRST GND
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt; /OE /ODT /T3 /T2 /T1 /RST NC NC NC VCC --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- This PLD is stateful and the initial state is unknown, so enter reset. --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 0 0 0 0 0 1 G 0 H H H H L X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- None of the other inputs should work while in reset--&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 0 0 0 1 0 0 G 0 H H H H L X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 0 1 0 0 0 0 G 0 H H H H L X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 1 0 0 0 0 0 G 0 H H H H L X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 1 0 0 0 0 0 0 G 0 H H H H L X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- Exit reset --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 0 0 0 0 1 0 G 0 H H H H H X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- Tests on, one by one. --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 0 1 0 0 0 0 G 0 H H H L H X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 1 0 0 0 0 0 G 0 H H L L H X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 1 0 0 0 0 0 0 G 0 H L L L H X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- ODT on and then off, test bits should remain. --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 0 0 0 1 0 0 G 0 L L L L H X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 0 0 1 0 0 0 G 0 H L L L H X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- ODT back on, just to ensure it clears below. --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 0 0 0 1 0 0 G 0 L L L L H X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- Reset should clear everything --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 0 0 0 0 0 1 G 0 H H H H L X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; C X 0 0 0 0 0 1 0 G 0 H H H H H X X X V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- We don&amp;#39;t us Z output, but check anyway --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt; 0 X 0 0 0 0 0 0 0 G 1 Z Z Z Z Z Z Z Z V &lt;span class="nt"&gt;&amp;lt;/vector&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/ic&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/custom&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/database&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/logicic&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-8"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We specify &lt;code&gt;name=&amp;quot;gp1&amp;quot;&lt;/code&gt; and &lt;code&gt;type=&amp;quot;5&amp;quot;&lt;/code&gt; on the &lt;code&gt;&amp;lt;ic&amp;gt;&lt;/code&gt; element. The name is arbitrary but it needs to be unique among the &lt;code&gt;&amp;lt;ic&amp;gt;&lt;/code&gt; elements in the file. The type is required and is always &lt;code&gt;5&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;All the &lt;code&gt;&amp;lt;vector&amp;gt;&lt;/code&gt; elements in the shared database have an &lt;code&gt;id&lt;/code&gt; element, but it&amp;rsquo;s ignored so I leave it out.&lt;/li&gt;
&lt;li&gt;The test vectors use some tokens not discussed above:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;X&lt;/code&gt; means &amp;ldquo;don&amp;rsquo;t care, don&amp;rsquo;t read or drive this pin&amp;rdquo;. I&amp;rsquo;m using it for all the NC pins.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C&lt;/code&gt; means &amp;ldquo;do a positive-going clock pulse before checking outputs&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Z&lt;/code&gt; is for expected high-impedance outputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Because this GAL implements sequential logic it&amp;rsquo;s important to place it in a &lt;strong&gt;known state&lt;/strong&gt; as the first step in our tests, because the cases are run many times in a loop. Coming back around with a different set of flip-flops set can cause surprising behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I run this test with minipro, passing my custom database with &lt;code&gt;--logicic&lt;/code&gt;.&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;$ minipro -T --logicic test.xml -p gp1
Using overridden database file test.xml
Found TL866II&amp;#43; 04.2.123 (0x27b)
Device code: 02106811
Serial code: N95SXK8LUBRHLHXHQG4Y
USB speed: 12Mbps (USB 1.1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
0000: C X 0 0 0 0 0 0 1 G 0 H H H H L X X X V
0001: C X 0 0 0 0 1 0 0 G 0 H H H H L X X X V
0002: C X 0 0 1 0 0 0 0 G 0 H H H H L X X X V
0003: C X 0 1 0 0 0 0 0 G 0 H H H H L X X X V
0004: C X 1 0 0 0 0 0 0 G 0 H H H H L X X X V
0005: C X 0 0 0 0 0 1 0 G 0 H H H H H X X X V
0006: C X 0 0 1 0 0 0 0 G 0 H H H L H X X X V
0007: C X 0 1 0 0 0 0 0 G 0 H H L L H X X X V
0008: C X 1 0 0 0 0 0 0 G 0 H L L L H X X X V
0009: C X 0 0 0 0 1 0 0 G 0 L L L L H X X X V
0010: C X 0 0 0 1 0 0 0 G 0 H L L L H X X X V
0011: C X 0 0 0 0 1 0 0 G 0 L L L L H X X X V
0012: C X 0 0 0 0 0 0 1 G 0 H H H H L X X X V
0013: C X 0 0 0 0 0 1 0 G 0 H H H H H X X X V
0014: 0 X 0 0 0 0 0 0 0 G 1 Z Z Z Z Z Z Z Z V
Logic test successful.
$&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
aria-label="Copy code"
data-copied-label="Copied!"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And that&amp;rsquo;s it. Really nicely designed facility I think.&lt;/p&gt;
&lt;h3 data-hextra-search-id="test-vector-summary"&gt;Test Vector Summary&lt;span class="hx:absolute hx:-mt-20" id="test-vector-summary"&gt;&lt;/span&gt;
&lt;a href="#test-vector-summary" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;&amp;lt;vector&amp;gt;&lt;/code&gt; element contains a string of N tokens, where N is the number of pins.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Whitespace is ignored; you can pack the tokens together or spread them out however you like.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s an error if you don&amp;rsquo;t have enough tokens, but if you have too many it silently becomes confused and you will end up with weird test behavior. So double-check the token count if you can&amp;rsquo;t figure out what&amp;rsquo;s happening.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is a summary of the supported tokens.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Token&lt;/th&gt;
&lt;th style="text-align: left"&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;V&lt;/code&gt;, &lt;code&gt;G&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Power pins, VCC and ground.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Input pin, drive low or high.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;L&lt;/code&gt;, &lt;code&gt;H&lt;/code&gt;, &lt;code&gt;Z&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Output pin, expect low, high, or high-impedance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;C&lt;/code&gt;, &lt;code&gt;K&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Clock pulse, positive-going and negative-going.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;X&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Don&amp;rsquo;t care. Don&amp;rsquo;t drive or read the pin.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description></item></channel></rss>