No, that's exactly right. At least it's exactly what I was thinking, too.
What it looks like is that last redundant value in the odds table is either coincidentally the only redundant value and which happens to be done in two consecutive lines. OR it is an attempt by the coder to prevent the pointer from going beyond the bounds of what W can be. In this case it would be odd coincidence.
So you are exactly right. By copying that last value and adding it in there to make a total of 8 lines to follow addwf pc in odds, it could potentially "fix it," if this is occurring. Even if it is occurring, it doesn't mean it is causing the problem you saw. In fact, after you described further, it doesn't sound like it. These lists are not performed in sequence, only one of these retlw's is the return point. So if this bad jump happend, "odds" would simply act like the 8th line below the addwf PC instruction happened to be the same line as the 8th line after same instruction in "pattern." It would not cause the "pattern" to "play" on the LEDs. It woudl just cause "odds" to have a perhaps unintended addition to its range, and w/e value was in that 8th spot might or might not cause any problem, but it wouldn't cause "part of the pattern" to light up on the LEDs (unless odds is played out to the LEDS, too, in which case it would only play that 1 frame of pattern, unless there is some other problem). Identifying what port the LEDs are connected to would help in finding the subroutine that actually takes these lookup tables and turns them into the flashing LEDs. The physical part of the problem is something you are still avoiding.
![Smiley :)](https://www.eevblog.com/forum/Smileys/default/xsmiley.gif.pagespeed.ic.R8GFI-pF6f.png)
This type of error, an occasional glitch is usually caused by
1. Bad jump, like what we are talking about just now. This manipulating PC is one of the big things. But in assembly, all kinds of logical errors by the coder can cause this, from mistakes in using BTFSS/C and otherwise.
2. Shared memory with bad handling.
3. Paging/banking mishandling.
So, to find the glitch, these are the type of things I would be looking for, primarily.
For 2, the memory problem, it is unfortunate that you have only one free register left in bank0. And also, the code uses INDF/FSR. So to figure out what is actually free in the other banks, you would first have to figure out how INDF/FSR works on this PIC and what values are in the range used by the program. Because the code does some calculations to manipulate FSR. Also, even if you do figure out free memory on other banks, using it will require bank bit or banksel, which will be cumbersome. Memory bank handling is essentially analagous to the paging using status bits 5,6 and/or pagesel/lcall to change the page in the hidden/high part of the PC (program counter/pointer), except to the analogous memory pointer.
If there were more free registers on bank 0, the approach I would use is to identify where memory/registers are shared, and see if they can't be separated. For instance, take counter_hi. It's doing something perhaps totally unrelated in auto1/2/3 (but I'm not sure). You could designate a new register as ... counter_higher (lol). And you could change counter_hi to counter_higher in say, just auto1/2/3. It might mess up the program in other ways, of course. *
Now the other issue you had with the machine always starting on a win, this might be an easy fix.
If it's starting the same every time, it must be because of the initialization of memory.
locate init2, and check those registers that are being cleared out. If you're lucky, simply putting ";" in front of the one of the usual suspects will cause the machine to start up randomly (at least pseudorandomly; undefined memory is sorta random on start, but not truly; for this reason, I think it would be better to just make it NOT payout on the first time).
*In fact, another thing comes to mind. Where that bcf counter_hi,4 instruction was (I forget the title;header, but it was error/instance #11 of counter_hi, IIRC ). Because of the way that this register is used in auto1/2/3, and because of what it does in feature/pattern, this instruction should really be replaced by a bit mask.** If somewhere else, say in autoX, counter reaches 64 or higher, when it gets used to this spot that incf counter_hi and then clears bit 4... well, when pattern is called, that will cause a bad jump.
**
;;;;;;;;;;;;;;;;;;;;;;;;;;
;bcf counter_hi,4
;
movlw b'00001111'
andwf counter_hi,f
;;;;;;;;;;;;;;;;;;;;;;;;;
Sorry if this is getting redundant. This is what I was talking about with adding some bit masks, as relating to making sure these addwf PC commands are staying in their intended playgrounds. So just keep in mind the reasons for this stuff... it's ultimately cuz you are interested in finding/fixing bad jumps and bad memory sharing. But it sounds like you're making some connections.