| ??? 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 test
Here'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 test
Now 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 test
Now 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 |



