??? 08/23/08 06:18 Read: times Msg Score: +1 +1 Informative |
#157681 - No fancy simulator required Responding to: ???'s previous message |
Alan said:
set a register with 00 0001
rotate left check for overflow reset value if overflow Let me guess that you wrote something like this: reset: mov a,#1 test: jb acc.5,reset rl a jmp testHere's what happens when this thing runs: INSTRUCTION RESULTING VALUE IN A ----------- -------------------- MOV 00000001 JB 00000001 RL 00000010 JMP 00000010 JB 00000010 RL 00000100 JMP 00000100 JB 00000100 RL 00001000 JMP 00001000 JB 00001000 RL 00010000 JMP 00010000 JB 00010000 RL 00100000 JMP 00100000 JB 00100000 MOV 00000001 JB 00000001 RL 00000010 JMP 00000010 JB 00000010 RL 00000100 JMP 00000100 JB 00000100 RL 00001000 JMP 00001000 JB 00001000 RL 00010000 JMP 00010000 JB 00010000 RL 00100000 JMP 00100000 JB 00100000 etc.From this, it's easy to see that the accumulator is less likely to contain 00000001 than any of the other values at the time of the interrupt. Without knowing exactly how you coded your loop and without then counting instruction cycles, we don't know how much less likely it is, but I'm pretty sure what I've shown here illustrates fundamentally what's going on. I'll leave it to you to investigate (as I did above), but I think you'll see a similar sort of effect with the DJNZ approach. Putting a delay into the loop (as suggested by the math expert) could make the problem less noticeable, but would not actually solve it. Suppose that you added some delay by adding some NOPs, like this: reset: mov a,#1 test: nop nop jb acc.5,reset rl a jmp testNow the execution would look like this: INSTRUCTION RESULTING VALUE IN A ----------- -------------------- MOV 00000001 NOP 00000001 NOP 00000001 JB 00000001 RL 00000010 JMP 00000010 NOP 00000010 NOP 00000010 JB 00000010 RL 00000100 JMP 00000100 NOP 00000100 NOP 00000100 JB 00000100 RL 00001000 JMP 00001000 NOP 00001000 NOP 00001000 JB 00001000 RL 00010000 JMP 00010000 NOP 00010000 NOP 00010000 JB 00010000 RL 00100000 JMP 00100000 NOP 00100000 NOP 00100000 JB 00100000 MOV 00000001 NOP 00000001 NOP 00000001 JB 00000001 RL 00000010 JMP 00000010 NOP 00000010 NOP 00000010 JB 00000010 RL 00000100 JMP 00000100 NOP 00000100 NOP 00000100 JB 00000100 RL 00001000 JMP 00001000 NOP 00001000 NOP 00001000 JB 00001000 RL 00010000 JMP 00010000 NOP 00010000 NOP 00010000 JB 00010000 RL 00100000 JMP 00100000 NOP 00100000 NOP 00100000 JB 00100000 etc.This is better, but the accumulator is still slightly less likely to contain 00000001 than any of the other values at the time of the interrupt. The situation gets better and better as you add more and more delay, but that in itself won't fix the problem. Insted, you need to craft the code so that each of the six numbers stay in the accumulator for the same amount of time. This variation shows what I mean: reset: mov a,#1 nop test: jb acc.5,reset rl a jmp testNow the execution looks like this: INSTRUCTION RESULTING VALUE IN A ----------- -------------------- MOV 00000001 NOP 00000001 JB 00000001 RL 00000010 JMP 00000010 JB 00000010 RL 00000100 JMP 00000100 JB 00000100 RL 00001000 JMP 00001000 JB 00001000 RL 00010000 JMP 00010000 JB 00010000 RL 00100000 JMP 00100000 JB 00100000 MOV 00000001 NOP 00000001 JB 00000001 RL 00000010 JMP 00000010 JB 00000010 RL 00000100 JMP 00000100 JB 00000100 RL 00001000 JMP 00001000 JB 00001000 RL 00010000 JMP 00010000 JB 00010000 RL 00100000 JMP 00100000 JB 00100000 etc.This is now perfect, if you accept the assumption that I have been making all along that all the instructions take the same amount of time. In reality, of course, you'll have to count actual clock cycles instead of instructions, and also account for the way you've actually coded the loop, including any other stuff that's in it. -- Russ |