Combinatorial PALs are built around an internal network of wires, whose interconnections are broken at flashing time. These wires connect the inputs to an array of AND gates, whose outputs are in turn connected to an array of OR gates (implementing a sum of products).
Even when the chip lock is set (thus blocking direct reading via a programmer), recovering the functions that map the internal connections is relatively easy: the output state is dependant only on the current state of the inputs and nothing else, making the creation of a truth table trivial: just feed the PAL every combination of inputs and record the outputs.
Things get a bit harder when we consider registered PALs: these ICs add an array of flip-flops to the network. These flip-flops have one of their outputs connected to a pin and the other feeding back into the internal network. A clock pin is also brought out to an external pin so that the flip-flops can be toggled.
When toggling the clock, the flip flop take their new value not only from a combinations of the inputs, but also from the feedback lines coming from out of the flip-flops themselves, i.e. when the clock is pulsed, the PAL changes its internal state, and the new state is dependant on the previous one.
From what I wrote in the introduction follows that a registered PAL device can be viewed as a stateful system whose current state is dependant on the previous one combined the state of the inputs at the moment the state is changed.
Luckily for us, the number of the possible states is known and dependant on the number of flip-flops inside the device (and, as every flip-flop is connected to a specific output, equal to the number of possible combinations that can be taken by the so-called registered outputs). Being connected directly to output pins, these flip-flop give us an important insight on the status of the PAL: we are able to identify exactly in which state it is at the moment.
To summarize and simplify, a registered PAL has the following types of outputs:
It is now clear that a registered PAL is a state machine whose current state is tied to the flip-flops, in turn connected to the registered outputs.
The number of these registered outputs depends on the PAL model, but is fixed and known and cannot be changed via programming. From this we can gather that a registered PAL device has 2^X possible states, where X is the number of registered outputs for that model.
I will call these states defined by the registered outputs "MacroStates", to distinguish them from another type of state, the SubStates, which I'll describe below.
While the MacroState is defined by the status of the registered outputs, we also need to take into account the state of the combinatorial outputs. The combinatorial outputs state is dependant only on the inputs and the registered outputs, and changes without the need of pulsing the clock (we can think each MacroState in a registered PAL as a single simple combinatorial PAL).
From this we get that for every MacroState we need to test all the input combinations in order to calculate their corresponding SubStates. For every MacroState we'll have 2^Y possible substates, where Y is the number of the combinatorial outputs, but we need to map them to 2^Z combinations of inputs (Z is the number of the input pins).
We can see that for a registered PAL we have:
Where:
The inner workings of a registered PAL can then be represented by a directed graph (or digraph), where every vertex is a MacroState, every edge is a link between a "starting" and a "destination" MacroState, and this link (which I'll call StateLink) is defined by the state of the inputs and the state of the registered outputs from the starting MacroState.
Reversing the inner working of the PAL device means that we need to find every possible StateLink (edge) in the digraph, and calculate all the SubStates for every MacroState (vertex) we can visit.
One this is done, we can use the graph we built to print out a truth table that represents all the possible states of the PAL, and from that, recover the logic equations.
We can summarize the algorithm to build the graph this way: