@Willxfmr, I do agree, documentation is essential, indirect addressing can be confusing even for seasoned programmers especially where indirect via an indirect is used, I have seen lots of code where the code has either been made difficult to understand deliberately or because of development to improve efficiency or standardisation it becomes difficult to understand.
I came across some S5 code, in that platform timers are 0-255, however, the code was using timers (timer number passed as a fixed word) from 256 onwards, I was not actually looking at the code as a job, just one of the technicians on site was trying to find a fault, I was aware that there are no timers above 255 & at first I was puzzled, I had a hunch that timers were only 8 bit so I created a timer which was indirectly addressed at 256, it was working & through monitoring timer 0 it was this timer, turns out as the timers are 8 bit addressing the upper byte is ignored so sees it as timer minus 256 i.e. only uses the lower byte. This was obviously an attempt to deter people from messing with the code. Also seen again in S5 where an MC5 instruction value in a dataword was used so by doing a special function (one of the RS instructions) the hex code in the dataword was processed as an MC5 instruction, this meant that with some other code that manipulated this dataword it would process that instruction, an example (not actual MC5 hex code as I do not have it now)
Lets assume the MC5 instruction is Load I0.5 so the MC5 code is as below
Load KHB5A0 // load a hex value for the MC5 instruction (note: the upper part of the 16bit word is the MC5 instruction & the lower is possibly an address
DO RSx // Sorry cannot remember the RS instruction but it processes the code so in reality it Loads I0.5
By incrementing the address bits the next time it is scanned it runs the load instruction with a different Input bit.
So in effect self modifying code it foxed me for a while & I considered it dangerous.